请参阅System.Array类的定义
public abstract class Array : IList, ...
从理论上讲,我应该能够写点东西并开心
int[] list = new int[] {};
IList iList = (IList)list;
我也应该能够从iList调用任何方法
ilist.Add(1); //exception here
我的问题不是为什么我会得到异常,而是为什么Array实现了IList?
请参阅System.Array类的定义
public abstract class Array : IList, ...
从理论上讲,我应该能够写点东西并开心
int[] list = new int[] {};
IList iList = (IList)list;
我也应该能够从iList调用任何方法
ilist.Add(1); //exception here
我的问题不是为什么我会得到异常,而是为什么Array实现了IList?
Answers:
因为数组允许按索引快速访问,所以IList
/ IList<T>
是唯一支持此功能的集合接口。因此,也许您真正的问题是:“为什么没有索引器的常量集合的接口?” 对此,我没有答案。
也没有用于集合的只读接口。我想念那些甚至超过带有索引器接口的恒定大小的东西。
IMO应当根据集合的功能,再有几个(通用)集合接口。而且名称也应该有所不同,List
因为带有索引器的东西确实是愚蠢的IMO。
IEnumerable<T>
ICollection<T>
IList<T>
我认为当前的收集接口设计不好。但是,由于它们具有告诉您哪些方法有效的属性(这是这些方法的约定的一部分),因此不会违反替代原理。
add
,因此不能代替需要该功能的事情。
IsFixedSize
和IsReadOnly
属性,它绝对违反了“告诉,不要问”原则和“最不惊奇的原则”。当您只打算在9种方法中的4种抛出异常时,为什么要实现一个接口?
备注一节的文档的IList
说
IList是ICollection接口的后代,并且是所有非泛型列表的基本接口。 IList实现分为三类:只读,固定大小和可变大小。只读的IList无法修改。固定大小的IList不允许添加或删除元素,但允许修改现有元素。可变大小的IList允许添加,删除和修改元素。
显然,数组属于固定大小类别,因此通过定义接口是有意义的。
Array
它确实Add
明确实现了该方法,从而降低了意外调用该方法的风险。
IList
,不允许修改和添加/删除。然后,文档不再正确。:P
因为并非所有IList
s都是可变的(请参阅IList.IsFixedSize
和IList.IsReadOnly
),所以数组的行为肯定类似于固定大小的列表。
如果您的问题确实是“为什么要实现一个非泛型接口”,那么答案是这些问题早在泛型出现之前就已存在。
IList
本身告诉您它可能是不可变的。如果实际上保证它是可变的,而数组告诉您否则,那么它将违反规则。
从不清楚如何处理只读集合以及Array是否为只读的时代开始,这就是我们的遗产。IList接口中有IsFixedSize和IsReadOnly标志。IsReadOnly标志意味着完全不能更改集合,而IsFixedSize意味着该集合允许修改,但不允许添加或删除项。
在.NET 4.5的时候,很明显,一些“中间”的接口都需要工作,只读集合,因此IReadOnlyCollection<T>
并IReadOnlyList<T>
进行了介绍。
这是一篇很棒的博客文章,描述了详细信息:.NET中的只读集合