- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我遇到过几次这种情况,我想通过 INotifyCollectionChanged
接口(interface)观察一个集合,但也希望能够访问该集合的任何元素。 INotifyCollectionChanged
接口(interface)不提供任何方式来访问元素,除了更改事件中涉及的元素(通常包含在 NotifyCollectionChangedEventArgs
中)。
这是我的想法:
INotifyCollectionChanged
的东西都是一个集合 (d'uh)。NotifyPropertyChangedEventArgs
包含指示更改位置的索引,我们知道可以通过索引访问元素。可以通过索引访问的集合是一个列表,因此要求任何 INotifyCollectionChanged
实现者也实现 IList
似乎是有意义的。这可以通过让 INotifyCollectionChanged
扩展 IList
轻松完成。
有谁知道为什么不是这样?
最佳答案
我认为您需要查找 SOLID软件设计原则,特别是Liskov Substitution Principle .
您问过为什么 INotifyCollectionChanged
接口(interface)不也扩展 IList
接口(interface)。让我使用 Liskov 替换原则用一个反问题来回答它:
Can I say an
INotifyCollectionChanged
is anIList
?
不,我不这么认为,原因如下:
INotifyCollectionChanged
传达的意思是实现此接口(interface)的类需要在其基础集合发生更改时通知其用户,无论该基础集合是 IList
还是 ICollection
,甚至IEnumerable
,我们不知道。它是 IList
接口(interface)的不同概念,它只是一个带有公开 indexer 的 ICollection
您提到了 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/
我开始涉足 WPF,我希望我的应用程序中的集合可以作为 ItemSource 使用。我尝试实现 INotifyCollectionChanged。我对此表示同意,但我必须在大约 15 个 dll 中引
在 ASP.Net 专门工作了几年之后,我现在才开始接触 WPF。我目前遇到的问题是我有一个自定义集合类,我需要将其绑定(bind)到列表框。除了从集合中删除一个项目外,一切似乎都在工作。当我尝试时出
我正在尝试创建一个ObservableConcurrentDictionary。该对象将在多线程应用程序中使用,并且其数据用于通过控件ItemsSource属性填充控件。 这是我想出的实现: publ
如果我创建一个新的 ObservableCollection , 和一个 CollectionChanged监听器如下: var c = new ObservableCollection(); c.C
我有一个类如下所示。为了简洁起见,我删除了所有功能 public class PersonCollection:IList {} 现在我又多了一个模型类,如下所示。 AddValueCommand 是
我的想法是,如果我在我的自定义集合上实现 INotifyCollectionChanged,DataGridView 将订阅 CollectionChanged 事件。 我的集合实现了 IListSo
我想要一个域模型集合类和一个 View 模型类,它们只反射(reflect)和投影域模型的元素——但它本身是只读的。 我的想法是这两种类型都实现了 INotifyCollectionChanged 接
我需要实现一个具有特殊功能的集合。另外,我想将这个集合绑定(bind)到一个ListView,所以我最终得到了下一个代码(我在论坛中省略了一些使它更短的方法): public class myColl
基本上,我想知道它在这里的实际效率如何。 示例代码: void GetItems() { foreach (var item in items) myObservableCol
我有一个用户控件。在那里我想维护一个集合作为依赖属性。假设该属性绑定(bind)到实现 INotifyCollectionChanged 的集合。 现在假设集合已添加或删除了一些项目,我如何在用户控件
我遇到过几次这种情况,我想通过 INotifyCollectionChanged 接口(interface)观察一个集合,但也希望能够访问该集合的任何元素。 INotifyCollectionChan
假设我有一个服务,它的接口(interface)是这样的: public interface IProxyRotator { ProxyRotationMode RotationMode {
我正在尝试实现一个可绑定(bind)集合(一个专门的堆栈),它需要显示在我的 Windows 8 应用程序的一页上,以及对其进行的任何更新。为此,我实现了 INotifyCollectionChang
嗨,我对数据表有一些麻烦。所以我需要的是每当我更改绑定(bind)的 DataTable 的 DataGrid 中的任何单元格时进行检测。 怎么做呢?使用 INotifyPropertyChanged
为 SO 写另一个问题时,我想到了一个我经常使用但从未真正反射(reflection)过的模式。但是现在,我不再确定这是不是正确的方法: 如果我有我的 WPF 控件将绑定(bind)到的集合,我几乎总
我正在尝试创建一个实现 INotifyCollectionChanged 的自定义集合并随时间报告内部项目列表的批量更改。这是一个更大项目的一部分,但我已经设法创建了一个示例应用程序来演示这个问题。请
背景:我试图通过实现 IEnumerable、INotifyPropertyChanged 和 INotifyCollectionChanged 来滚动我自己的可观察集合。它工作正常,但是当我进行数据
我正在尝试从实现 INotifyCollectionChanged 的集合的 CollectionChanged 事件中获取一些自定义对象。 MyControl_MyCollectionChanged
我正在制作一个可观察的类(class)。添加方法工作正常。但是后来我尝试调用 Remove() 方法时出现此错误: "Added item does not appear at given index
我有一个样本信息数组,在后台线程中不断刷新。 目前,我经常使用 DispatcherTimer 将此数组分配给数据网格的 ItemsSource 属性。这行得通,但它会重置任何视觉位置,例如,如果用户
我是一名优秀的程序员,十分优秀!