为什么数组实现IList?
请参阅System.Array类的定义
public abstract class Array : IList, ...
理论上来说,我应该可以写下这一点,并开心
int[] list = new int[] {}; IList iList = (IList)list;
我也应该能够从iList调用任何方法
ilist.Add(1); //exception here
我的问题不是为什么我得到一个exception,而是为什么Array实现IList ?
因为数组允许通过索引进行快速访问,而IList
/ IList<T>
是唯一支持这个function的集合接口。 所以也许你真正的问题是“为什么没有与索引器常量集合的接口? 而我没有答案。
对于集合,没有只读接口。 而且我甚至比索引器界面还要小。
国际海事组织应该有更多的(通用)收集接口取决于集合的function。 而且名字也应该是不一样的,用索引器List
一些东西实在是愚蠢的IMO。
- 只是枚举
IEnumerable<T>
- 只读,但没有索引(.Count,.Contains,…)
- 可resize,但没有索引器,即设置像(添加,删除,…)当前
ICollection<T>
- 只读索引器(索引器,索引,…)
- 具有索引器的恒定大小(带有setter的索引器)
- 索引器(Insert,…)当前的
IList<T>
可变大小
我认为目前的收集界面是不好的devise。 但是,由于它们具有告诉你哪些方法是有效的属性(这是这些方法的合同的一部分),所以它并没有打破替代原则。
IList
文档的评论部分说
IList是ICollection接口的后代,是所有非generics列表的基本接口。 IList实现分为三类:只读,固定大小和可变大小 。 只读的IList不能被修改。 固定大小的IList不允许添加或删除元素,但可以修改现有元素。 可变大小的IList允许添加,删除和修改元素。
很显然,数组属于固定大小的类,所以通过接口的定义是有意义的。
因为不是所有的IList
都是可变的 (参见IList.IsFixedSize
和IList.IsReadOnly
),数组的行为就像固定大小的列表。
如果你的问题真的是“为什么它实现了一个非generics接口”,那么答案就是这些在generics出现之前就已经存在了。
这是我们从不知道如何处理只读集合以及是否只读数组的时代所遗留下来的。 IList接口中有IsFixedSize和IsReadOnly标志。 IsReadOnly标志意味着集合根本不能被改变,IsFixedSize意味着集合确实允许修改,但不能添加或删除项目。
在.Net 4.5的时候,显然有些“中间”接口需要与只读集合一起工作,所以引入了IReadOnlyCollection<T>
和IReadOnlyList<T>
。
下面是一篇很棒的博客post,描述了这些细节: .NET中的只读集合
IList接口的定义是“表示可以通过索引单独访问的对象的非generics集合”。 数组完全满足这个定义,所以必须实现接口。 调用Add()方法时的exception是“System.NotSupportedException:Collection是一个固定的大小”,并发生,因为数组不能dynamic增加其容量。 其容量是在创build数组对象时定义的。