检测词典中包含的值是否已更改

时间:2009-03-13 21:00:11

标签: c# .net

如果我从IDictionary派生一个类,我怎么能确定任何给定的V在添加到底层集合后没有改变?

6 个答案:

答案 0 :(得分:3)

有很多方法,但这取决于......

如果添加到字典中的值类型包含“已更改”类型的事件,请订阅它。

如果值类型不包含此类事件,但您控制源代码,请添加该事件并订阅它。

如果值类型不包含此类事件,并且您不控制源代码,请考虑使用克隆值或其他内容维护值的卷影副本,并进行比较。

我担心在最后一种情况下,你不控制类型并且它不包含事件,你别无选择,只能以某种方式记录每个值的当前状态,然后与该状态进行比较,看它是否已经改变。

答案 1 :(得分:2)

如果它是引用类型,我会在你想要包含在IDictionary中的类上实现INotifyPropertyChanged。在“添加”项目订阅PropertyChanged事件时,请确保在删除项目时取消订阅;否则你将'泄漏'对包含的对象实例的引用(它不会被收集)。像这样:

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);
    }
}

答案 2 :(得分:1)

如果在类上实现IDictionary,则可以向对象上的setter添加isdirty或其他事件或跟踪。但是,如果对象很复杂并且对象的子属性已更改,则可能会使事情变得更加棘手。这取决于您的使用环境 - 您是否希望在对象发生变化时将其作为事件驱动,或者您只是需要知道?如果它在getter上,你可以随时检查它们上次获取或添加时的哈希值。

答案 3 :(得分:0)

使用值存储更改计数,并在执行修改时增加更改计数。然后,您可以检查更改计数以查看对象是否已更改。

答案 4 :(得分:0)

所以我理解的是,实际上没有简单的方法可以知道存储的值是否已经改变。这意味着如果我真的需要这些信息(我这样做),那么我必须偶尔走一下值列​​表并检查它们是否已经改变。

我需要分析这样做的影响。希望我可以实现它,以便它发生在一个单独的线程上,并且在比较中非常有效。这也意味着我必须将V限制为IComparable。

答案 5 :(得分:0)

在派生类中定义默认的 Item()属性设置器。像这样,在VB上带有T字典的示例,布尔值:

Private Dict As New Dictionary (Of T, Boolean)
Public Event ValueChanged (key as T, value as Boolean)

Default Public Property Item(key as T) as Boolean Implements IDictionary(Of T, Boolean).Item
    Get
        Return Dict(key)
    End Get
    Set(value as Boolean)
        Dict(key) = value
        RaiseEvent ValueChanged(key, value) 'this is it!
    End Set
End Property