Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# Fastest way to know something in object has changed?

Tags:

c#

I want to know, if the value of any of the private or public fields has changed. Is there any way other than over-riding GetHashCode() or calculating CRC?

The algorithm should be fast too.

like image 371
Brajesh Avatar asked Oct 01 '10 22:10

Brajesh


3 Answers

Normally, this would be done with the INotifyPropertyChanged interface (link). It is really only practical to use it with properties, though, not fields. However, you could create a private property for each of your private fields. Once you have everything as a property, edit the setter so that you check if the value has changed, then call NotifyPropertyChanged() if it has.

Example:

public event PropertyChangedEventHandler PropertyChanged;

private int _foo;

public int Foo
{
    get { return _foo; }
    set
    {
        if (_foo != value)
        {
            _foo = value;
            NotifyPropertyChanged("Foo");
        }
    }
}

private void NotifyPropertyChanged(string info)
{
    if (PropertyChanged != null)
    {
        PropertyChanged(this, new PropertyChangedEventArgs(info));
    }
}
like image 102
devuxer Avatar answered Sep 24 '22 19:09

devuxer


You may want to encapsulate all your data (which you want to monitor for change) inside the get/set accessors (a.k.a. properties).

Then, in set accessor, check if value has changed, set it to new value, and:

  • set _dirty to true (if you need to check it later)

or

  • raise some event to your liking

Some notes on CRC - even if you have non-colliding CRC/HASH algoritam for your object, you must have original hash somewhere. But simple hashes are likely to duplicate, so you again have speed issue.

like image 22
Daniel Mošmondor Avatar answered Sep 21 '22 19:09

Daniel Mošmondor


If it needs to work for any type and needs to detect any modification, with no false negatives or false positives, I don't see any better way than a copy of all field values for reference. Since you need it to be fast, I would recommend the following:

  1. Write a routine that uses reflection to perform a shallow copy of all field values.

  2. Write a routine that compares the fields by value (if you're looking for changes in nested structures, like arrays or collections, your problem is much tougher.)

  3. Once the above work, you can use IL Emit and write code that does the Reflection once and emits code for the shallow-copy and comparison operations. Now you have some DynamicMethod instances you can use for each operation. These are quite fast, once emitted and jitted.

like image 38
Dan Bryant Avatar answered Sep 23 '22 19:09

Dan Bryant