C# 检测字典中包含的值是否已更改

C# 检测字典中包含的值是否已更改,c#,.net,C#,.net,如果我从IDictionary派生一个类,如何确定任何给定的V在添加到基础集合后没有发生更改?如果在类上实现IDictionary,则可以向对象上的setter添加isdirty或其他事件或跟踪。但是,如果对象很复杂,并且对象的子属性已更改,则会使事情变得更棘手。这取决于您的使用环境-您是希望在对象更改时由事件驱动,还是只需要知道?如果是在getter上,则始终可以检查上次获取或添加对象时的对象哈希。使用该值存储更改计数,并在执行修改时增加该值。然后,您可以检查更改计数以查看对象是否已更改。有很

如果我从IDictionary派生一个类,如何确定任何给定的V在添加到基础集合后没有发生更改?

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

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

有很多方法,但这取决于

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

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

如果值类型不包含这样的事件,并且不控制源代码,请考虑用克隆值或某些东西来维护值的阴影复制,并进行比较。


恐怕在最后一种情况下,如果您不控制类型,并且它不包含事件,那么您就别无选择,只能记录每个值的当前状态,然后再与该状态进行比较,看看它是否发生了变化。

我的理解是,要知道存储的值是否已更改,确实没有简单的方法。这意味着,如果我真的需要这些信息(我确实需要),那么我必须偶尔浏览一下值列表,看看它们是否发生了变化

我需要描述这样做的影响。希望我能实现它,使它发生在一个单独的线程上,并且在比较时非常有效。这还意味着我必须将V约束为IComparable。

如果是引用类型,我将在您希望包含在IDictionary中的类上实现。在“添加”项目订阅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);
    }
}
公共事件事件处理程序CollectionItemPropertyChanged;
公共无效添加(对象键、对象项)
{
INotifyPropertyChanged notify=作为INotifyPropertyChanged的项目;
如果(通知!=null)
{
notify.PropertyChanged+=OnCollectionItemPropertyChanged;
}
}
CollectionItemPropertyChanged上的私有无效(对象发送方,PropertyChangedEventArgs e)
{
if(this.CollectionItemPropertyChanged!=null)
{
CollectionItemPropertyChanged eventArgs=new CollectionItemPropertyChanged();
eventArgs.Item=发件人;
eventArgs.Property=e.PropertyName;
this.this.CollectionItemPropertyChanged(this,eventArgs);
}
}
在派生类中重新定义default Item()属性setter。如下图所示,在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

这应该作为澄清而不是可能的答案添加到原始问题中。