C# 为什么可观察字典是通过实现接口来实现的?
好的,我一直在寻找一个字典,当一段数据被更改时,它会抛出一个事件。我经常遇到的一个链接是: 在检查IDictionary接口和Dictionary类之后,我可以清楚地看到CRUD(创建-读取-更新-删除)。理论上,所有词典都应该基于此功能 在我看来,实现一个可观察的字典应该像C# 为什么可观察字典是通过实现接口来实现的?,c#,oop,collections,dictionary,observablecollection,C#,Oop,Collections,Dictionary,Observablecollection,好的,我一直在寻找一个字典,当一段数据被更改时,它会抛出一个事件。我经常遇到的一个链接是: 在检查IDictionary接口和Dictionary类之后,我可以清楚地看到CRUD(创建-读取-更新-删除)。理论上,所有词典都应该基于此功能 在我看来,实现一个可观察的字典应该像 public class test<K,V> : Dictionary<K,V>, INotifyCollectionChanged, INotifyPropertyChanging { p
public class test<K,V> : Dictionary<K,V>, INotifyCollectionChanged, INotifyPropertyChanging
{
public event NotifyCollectionChangedEventHandler CollectionChanged;
public event PropertyChangedEventHandler PropertyChanged;
private const string pCount = "Count";
private const string pKeys = "Keys";
private const string pValues = "Values";
public V this[K key]
{
get
{
return base[key];
}
set
{
object old = base[key];
base[key] = value;
if (CollectionChanged != null)
CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, new KeyValuePair<K, V>(key, value), new KeyValuePair<K, V>(key, (V)old)));
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(pValues));
}
}
public override void Add(K key, V value)
{
base.Add(key, value);
if(CollectionChanged!=null)
CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, new KeyValuePair<K,V>(key, value)));
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(pCount));
PropertyChanged(this, new PropertyChangedEventArgs(pKeys));
PropertyChanged(this, new PropertyChangedEventArgs(pValues));
}
}
public override void Remove(K key)
{
object removed = base[key];
base.Remove(key);
if (CollectionChanged != null)
CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, removed));
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(pCount));
PropertyChanged(this, new PropertyChangedEventArgs(pKeys));
PropertyChanged(this, new PropertyChangedEventArgs(pValues));
}
}
}
公共类测试:字典、INotifyCollectionChanged、inotifyPropertyChanged
{
公共事件通知CollectionChangedEventHandler CollectionChanged;
公共事件属性更改事件处理程序属性更改;
私有常量字符串pCount=“Count”;
private const string pKeys=“Keys”;
private const string pValues=“Values”;
公共V本[K键]
{
得到
{
返回基[键];
}
设置
{
对象旧=基[键];
基[键]=值;
如果(CollectionChanged!=null)
CollectionChanged(此,新的NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace,新的KeyValuePair(键,值),新的KeyValuePair(键,(V)旧));
if(PropertyChanged!=null)
PropertyChanged(这是新的PropertyChangedEventArgs(pValues));
}
}
公共覆盖无效添加(K键,V值)
{
添加(键、值);
如果(CollectionChanged!=null)
CollectionChanged(此,新的NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add,新的KeyValuePair(键,值));
if(PropertyChanged!=null)
{
PropertyChanged(此为新PropertyChangedEventArgs(pCount));
PropertyChanged(即新PropertyChangedEventArgs(pKeys));
PropertyChanged(这是新的PropertyChangedEventArgs(pValues));
}
}
公共覆盖无效删除(K键)
{
移除的对象=基[键];
底座。移除(键);
如果(CollectionChanged!=null)
CollectionChanged(此,新的NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove,removed));
if(PropertyChanged!=null)
{
PropertyChanged(此为新PropertyChangedEventArgs(pCount));
PropertyChanged(即新PropertyChangedEventArgs(pKeys));
PropertyChanged(这是新的PropertyChangedEventArgs(pValues));
}
}
}
编辑:添加更多内容,使其更像示例,并帮助澄清问题
我不明白为什么所有这些精巧的词典都在制作中,有什么我遗漏的吗?有人能给我解释一下吗
就我所见,他们好像都在重新发明轮子,这与可重用代码背道而驰,而可重用代码正是OO的重点。我真的觉得我一定错过了什么。INotifyPropertyChanged和INotifyCollectionChanged的要点在于它们是由.Net自己使用的(比如WPF和winforms)
您自己的自定义
OnValueAdd
等。委托在您自己的类之外是未知的,并且它们不能被.Net的自动更改通知机制使用。INotifyPropertyChanged和INotifyCollectionChanged
的要点是它们被.Net自己的类使用(例如WPF,在较小程度上是winforms)
您自己的自定义
OnValueAdd
等。在您自己的类之外不知道委托,并且.Net的自动更改通知机制无法使用它们。您无法执行您尝试执行的操作有以下几个原因:
索引器、添加和删除方法不是虚拟的。您不能重写Add
或Remove
方法,因为它们不是虚拟的
因为您没有覆盖这些方法,所以只要将对象键入IDictionary
或Dictionary
类型,事件就不会被触发,充其量只能对它们进行阴影处理
通过使用组合而不是继承,如您链接到的示例所示,给定字典对象的人无法在不触发事件的情况下添加项目,因为无法直接访问字典。有几个原因导致您无法执行您尝试执行的操作:
索引器、添加和删除方法不是虚拟的。您不能重写Add
或Remove
方法,因为它们不是虚拟的
因为您没有覆盖这些方法,所以只要将对象键入IDictionary
或Dictionary
类型,事件就不会被触发,充其量只能对它们进行阴影处理
通过使用组合而不是继承,如您链接到的示例所示,给定字典对象的人无法在不触发事件的情况下添加项目,因为无法直接访问字典。您的示例未实现inotifPropertyChanged
或inotifCollectionChanged
。您的示例没有实现INotifyPropertyChanged
或INotifyCollectionChanged
。我认为,我对该特定实现的了解不够,这让我稍微偏离了这个问题。我想说的是,作者可以简单地从字典继承,然后扩展类来添加这些新内容。我只是不明白为什么每个这样做的人都会重新创建整个dictionary对象,尤其是当大多数重新创建的类都只是包装原始类时。@Aelphaeis在该示例中,不仅仅是在项目被删除/添加到dictionary时通知。我编辑了问题以添加什么内容我已经看到他有我没有的,并且让我更清楚地知道我说的是什么意思,就像他们在重新发明轮子一样