tags:

views:

207

answers:

5

If I derive a class from IDictionary, how can I be certain that any given V has not changed after it is added to the underlying collection?

+1  A: 

If you implement IDictionary on a class, you can add an isdirty or some other event or tracking to the setter(s) on your object. However, if the object is complex and a sub-property of the object has changed, that can make things a little more sticky. It depends on the context of your usage - do you want this to be event-driven when an object changes, or do you just need to know? If it's on a getter, you can always check the hash of the objects from the last time they were gotten or added.

Rex M
A: 

Store a change count with the value, and increase it whenever a modification is performed. Then you can check the change count to see if the object has been changed.

Strilanc
+1  A: 

There's many ways, but it depends...

If the value type added to the dictionary contains a "Changed" type of event, subscribe to it.

If the value type doesn't contain such an event, but you control the source code, add the event and subscribe to it.

If the value type doesn't contain such an event, and you don't control the source code, consider maintaining a shadow copy of the values with cloned values or something, and do comparisons.

I'm afraid that in the last case there, where you don't control the type and it doesn't contain events, you're left with no choice but to somehow make a record of the current state of each value, and later on compare to that state to see if it has changed.

Lasse V. Karlsen
A: 

So what I am understanding, there is really no easy way to handle knowing if the value stored has changed. This implies that if I truely need this information (which I do) then I must occassionally walk the list of values and check to see if they have changed.

I will need to profile the impact of doing so. Hopefully I can implement it so that it happens on a separate thread and is very efficent at the comparision. It also means that I must constrain the V to being IComparable.

This should be added to the original question as a clarification, not as a possible answer.
Rex M
+1  A: 

I would implement INotifyPropertyChanged on the class that you intend to be contained in your IDictionary, if it's a reference type. On "Add" of item subscribe to the PropertyChanged event, ensure you unsubscribe when you remove items; otherwise you'll 'leak' the reference to the contained object instance (it won't be collected). Something like this:

public event EventHandler<CollectionItemPropertyChangedEventArgs> CollectionItemPropertyChanged; 


public void Add(object key, object item)
{
    INotifyPropertyChanged notify = item as INotifyPropertyChanged; 
    if(notify != null)
    {
        notify.PropertyChanged += OnCollectionItemPropertyChanged; 
    }
}

private void OnCollectionItemPropertyChanged(object sender, PropertyChangedEventArgs e)
{
    if(this.CollectionItemPropertyChanged != null)
    {
        CollectionItemPropertyChanged eventArgs = new CollectionItemPropertyChanged();
        eventArgs.Item = sender;
        eventArgs.Property = e.PropertyName; 
        this.this.CollectionItemPropertyChanged(this, eventArgs);
    }
}
Phil Price