【问题标题】:Why are observable dictionaries implemented by implementing interfaces?为什么可观察字典是通过实现接口来实现的?
【发布时间】:2013-09-09 14:07:22
【问题描述】:

好的,所以我一直在寻找一个字典,它会在一条数据发生更改时引发一个事件。我不断遇到的链接之一是:http://blogs.microsoft.co.il/blogs/shimmy/archive/2010/12/26/observabledictionary-lt-tkey-tvalue-gt-c.aspx

检查 IDictionary 接口和 Dictionary 类后,我可以清楚地看到 CRUD(创建读取更新删除)。理论上所有的字典都应该建立在这个功能之上。

在我看来,实现一个可观察字典应该很简单

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

编辑:添加更多内容以使其更像示例并帮助澄清问题

我不明白为什么要制作所有这些精心制作的词典,是我遗漏了什么吗?有人可以向我解释一下吗?

感觉就像他们都在重新发明轮子,据我所知,这违背了可重用代码,这是 OO 的重点。我真的觉得我一定是错过了什么。

【问题讨论】:

  • 您的示例没有实现INotifyPropertyChanged 或INotifyCollectionChanged。

标签: c# oop collections dictionary observablecollection


【解决方案1】:

你不能做你想做的事有几个原因:

索引器、添加和删除方法不是虚拟的。您不能 override Add 或 Remove 方法,因为它们不是虚拟的。

因为您没有覆盖这些方法,所以您最多可以隐藏它们,只要将对象键入为 IDictionary 或 Dictionary,就不会触发事件。

通过使用组合而不是继承,如您链接到的示例所示,给定字典对象的人无法在不触发事件的情况下添加项目,因为无法直接访问字典.

【讨论】:

  • 现在我明白了,谢谢你。这不适用于我想使用它的特定原因;但是,现在我明白了为什么它总是从接口实现而不是继承。
【解决方案2】:

INotifyPropertyChanged 和INotifyCollectionChanged 的意义在于它们被.Net 自己的DataBinding 使用(例如WPF 和较小程度上的winforms)。

您自己的自定义OnValueAdd等委托在您自己的类之外是不知道的,并且它们不能被.Net的自动更改通知机制使用。

【讨论】:

  • 我认为我对那个特定实现的目的缺乏了解,这让我有点偏离了这个问题。我的意思是,作者可以简单地从 Dictionary 继承,然后扩充类以添加这些新东西。我只是不明白为什么这样做的每个人都会重新创建整个字典对象,尤其是当重新创建的大多数类只是包装原始类时。
  • @Aelphaeis 在该示例中,不仅仅是在项目被删除/添加到字典时发出通知。
  • 我已经编辑了这个问题,以添加我所看到的他有我没有的东西,并更清楚我的意思是当我说感觉就像他们正在重新发明车轮。现在它看起来更像示例了,除了大多数方法都使用了字典的默认实现。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多