c# - 为什么 INotifyCollectionChanged 不扩展 IList?

标签 c# .net collections

我遇到过几次这种情况,我想通过 INotifyCollectionChanged 接口(interface)观察一个集合,但也希望能够访问该集合的任何元素。 INotifyCollectionChanged 接口(interface)不提供任何方式来访问元素,除了更改事件中涉及的元素(通常包含在 NotifyCollectionChangedEventArgs 中)。

这是我的想法:

  1. 我们知道任何实现 INotifyCollectionChanged 的东西都是一个集合 (d'uh)。
  2. 由于 NotifyPropertyChangedEventArgs 包含指示更改位置的索引,我们知道可以通过索引访问元素。

可以通过索引访问的集合是一个列表,因此要求任何 INotifyCollectionChanged 实现者也实现 IList 似乎是有意义的。这可以通过让 INotifyCollectionChanged 扩展 IList 轻松完成。

有谁知道为什么不是这样?

最佳答案

我认为您需要查找 SOLID软件设计原则,特别是Liskov Substitution Principle .

您问过为什么 INotifyCollectionChanged 接口(interface)不也扩展 IList 接口(interface)。让我使用 Liskov 替换原则用一个反问题来回答它:

Can I say an INotifyCollectionChanged is an IList?

不,我不这么认为,原因如下:

  1. INotifyCollectionChanged 传达的意思是实现此接口(interface)的类需要在其基础集合发生更改时通知其用户,无论该基础集合是 IList 还是 ICollection,甚至IEnumerable,我们不知道。它是 IList 接口(interface)的不同概念,它只是一个带有公开 indexerICollection

  2. 您提到了 NotifyPropertyChangedEventArgs(我相信您指的是 NotifyCollectionChangedEventArgs)公开了指示集合更改位置的索引属性。然而,这并不意味着这些属性必须通过 IList 的索引器公开项目。它可以是任意数字,魔法常量,等等。由实现类决定如何公开索引。

为了演示这一点,请看一下我实现了 INotifyCollectionChanged 的自定义类:

public class MyCustomCollection : INotifyCollectionChanged
{
    // This is what I meant by the "underlying collection", can be replaced with
    // ICollection<int> and it will still work, or even IEnumerable<int> but with some
    // code change to store the elements in an array
    private readonly IList<int> _ints;

    public MyCustomCollection()
    {
        _ints = new List<int>();
    }

    public event NotifyCollectionChangedEventHandler CollectionChanged;

    public void AddInt(int i)
    {
        _ints.Add(i);
        OnCollectionChanged(new NotifyCollectionChangedEventArgs(
            NotifyCollectionChangedAction.Move, 
            (IList)_ints, 
            _ints.Count,
            _ints.Count - 1));
    }

    protected virtual void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
    {
        var handler = CollectionChanged;
        if (handler != null)
        {
            handler(this, e);
        }
    }
}

希望这能回答您的问题。

关于c# - 为什么 INotifyCollectionChanged 不扩展 IList?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27939451/

相关文章:

java - 流数据的理想 Java 数据结构

c# - 删除时无法将 NULL 插入到列中

c# - 如何访问 ApiController 中的 Response

c# - 将 VB.NET DLL 导入 C#.Net 项目

.net - Threading.Timer与Forms.Timer

java - 提高合并两个 ArrayList 的性能

c# - C# 中相等性的最少代码

c# - 从 Windows Phone 7 连接到 MYSQL

.net - 在 VB.Net 中手动在 Reportviewer 中加载 .rdlc 报告

c# - 通过方法返回 list<t> 的最佳方式是什么?