为什么数组要实现IList?

发布于 2024-11-06 08:35:33 字数 352 浏览 1 评论 0原文

查看 System.Array 类的定义

public abstract class Array : IList, ...

理论上,我应该能够编写这一点并且很高兴

int[] list = new int[] {};
IList iList = (IList)list;

我也应该能够从 iList 调用任何方法

 ilist.Add(1); //exception here

我的问题不是为什么我会收到异常,而是为什么 Array 实现 IList

See the definition of System.Array class

public abstract class Array : IList, ...

Theoretically, I should be able to write this bit and be happy

int[] list = new int[] {};
IList iList = (IList)list;

I also should be able to call any method from the iList

 ilist.Add(1); //exception here

My question is not why I get an exception, but rather why Array implements IList?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

挽清梦 2024-11-13 08:35:33

因为数组允许通过索引快速访问,而 IList/IList 是唯一支持此功能的集合接口。因此,也许您真正的问题是“为什么没有用于带有索引器的常量集合的接口?”对此我没有答案。

集合也没有只读接口。我错过了那些甚至超过带有索引器接口的恒定大小的东西。

IMO 应该有更多(通用)集合接口,具体取决于集合的功能。而且名称也应该不同,在我看来,带有索引器的 List 确实很愚蠢。

  • 只是枚举 IEnumerable
  • 只读,但没有索引器(.Count、.Contains、...)
  • 可调整大小,但没有索引器,即设置为(添加、删除、...)当前 ICollection< ;T>
  • 带索引器的只读(indexer、indexof,...)
  • 带索引器的常量大小(带 setter 的索引器)
  • 带索引器的可变大小(Insert,...) current IListIList

我认为当前的集合接口设计很糟糕。但由于它们具有告诉您哪些方法有效的属性(这是这些方法契约的一部分),因此它不会违反替换原则。

Because an array allows fast access by index, and IList/IList<T> are the only collection interfaces that support this. So perhaps your real question is "Why is there no interface for constant collections with indexers?" And to that I have no answer.

There are no readonly interfaces for collections either. And I'm missing those even more than a constant sized with indexers interface.

IMO there should be several more (generic) collection interfaces depending on the features of a collection. And the names should have been different too, List for something with an indexer is really stupid IMO.

  • Just Enumeration IEnumerable<T>
  • Readonly but no indexer (.Count, .Contains,...)
  • Resizable but no indexer, i.e. set like (Add, Remove,...) current ICollection<T>
  • Readonly with indexer (indexer, indexof,...)
  • Constant size with indexer (indexer with a setter)
  • Variable size with indexer (Insert,...) current IList<T>

I think the current collection interfaces are bad design. But since they have properties telling you which methods are valid (and this is part of the contract of these methods), it doesn't break the substitution principle.

猫七 2024-11-13 08:35:33

文档的备注部分 <代码> IList 说:

IList 是
ICollection 接口并且是基础
所有非通用列表的接口。
IList 实现分为三种
类别:只读、固定大小和
可变大小。只读 IList
无法修改。固定大小的 IList
不允许添加或删除
元素,但它允许
修改现有元素。一个
可变大小的 IList 允许
添加、删除和修改
元素。


显然,数组属于固定大小类别,因此根据接口的定义,这是有意义的。

The remarks section of the documentation for IList says:

IList is a descendant of the
ICollection interface and is the base
interface of all non-generic lists.
IList implementations fall into three
categories: read-only, fixed-size, and
variable-size
. A read-only IList
cannot be modified. A fixed-size IList
does not allow the addition or removal
of elements, but it allows the
modification of existing elements. A
variable-size IList allows the
addition, removal, and modification of
elements.

Obviously, arrays fall into the fixed-size category, so by the definition of the interface it makes sense.

云柯 2024-11-13 08:35:33

因为并非所有IList都是可变的(请参阅IList.IsFixedSizeIList.IsReadOnly),并且数组的行为当然就像固定大小的列表一样。

如果您的问题确实是“为什么它实现非泛型接口”,那么答案是这些在泛型出现之前就已经存在了。

Because not all ILists are mutable (see IList.IsFixedSize and IList.IsReadOnly), and arrays certainly behave like fixed-size lists.

If your question is really "why does it implement a non-generic interface", then the answer is that these were around before generics came along.

少女七分熟 2024-11-13 08:35:33

这是我们从不清楚如何处理只读集合以及数组是否是只读的时代遗留下来的。 IList 接口中有 IsFixedSize 和 IsReadOnly 标志。 IsReadOnly 标志意味着集合根本无法更改,IsFixedSize 意味着集合允许修改,但不允许添加或删除项目。

在 .Net 4.5 时,很明显需要一些“中间”接口来处理只读集合,因此 IReadOnlyCollectionIReadOnlyList介绍了。

这是一篇很棒的博客文章,描述了详细信息: 只读集合在.NET中

It's a legacy that we have from the times when it wasn't clear how to deal with read only collections and whether or not Array is read only. There are IsFixedSize and IsReadOnly flags in the IList interface. IsReadOnly flag means that collection can't be changed at all and IsFixedSize means that collection does allow modification, but not adding or removal of items.

At the time of .Net 4.5 it was clear that some "intermediate" interfaces are required to work with read only collections, so IReadOnlyCollection<T> and IReadOnlyList<T> were introduced.

Here is a great blog post describing the details: Read only collections in .NET

血之狂魔 2024-11-13 08:35:33

IList接口的定义是“表示可以通过索引单独访问的对象的非泛型集合”。 Array完全满足这个定义,因此必须实现该接口。
调用 Add() 方法时出现异常“System.NotSupportedException:集合具有固定大小”,这是因为数组无法动态增加其容量而发生的。它的容量是在创建数组对象时定义的。

Definition of IList interface is "Represents a non-generic collection of objects that can be individually accessed by index.". Array completely satisfies this definition, so must implement the interface.
Exception when calling Add() method is "System.NotSupportedException: Collection was of a fixed size" and occurred because array can not increase its capacity dynamically. Its capacity is defined during creation of array object.

书间行客 2024-11-13 08:35:33

让数组实现 IList(以及传递性的 ICollection)简化了 Linq2Objects 引擎,因为将 IEnumerable 转换为 IList/ICollection 也适用于数组。

例如,Count() 最终会在底层调用 Array.Length,因为它被转换为 ICollection 并且数组的实现返回 Length。

如果没有这个,Linq2Objects 引擎将不会对数组进行特殊处理并且执行得很糟糕,或者他们需要加倍代码来添加对数组的特殊情况处理(就像它们对 IList 所做的那样)。他们一定选择让数组实现 IList。

这就是我对“为什么”的看法。

Having an array implement IList (and transitively, ICollection) simplified the Linq2Objects engine, since casting the IEnumerable to IList/ICollection would also work for arrays.

For example, a Count() ends up calling the Array.Length under-the-hood, since it's casted to ICollection and the array's implementation returns Length.

Without this, the Linq2Objects engine would not have special treatment for arrays and perform horribly, or they'd need to double the code adding special-case treatment for arrays (like they do for IList). They must've opted to make array implement IList instead.

That's my take on "Why".

清旖 2024-11-13 08:35:33

还有实现细节 LINQ Last 检查 IList ,如果它没有实现列表,它们将需要 2 个检查来减慢所有 Last 调用的速度,或者在数组上使用 Last ,时间复杂度为 O(N)

Also implementation details LINQ Last checks for IList , if it did not implement list they would need either 2 checks slowing down all Last calls or have Last on an Array taking O(N)

贩梦商人 2024-11-13 08:35:33

Array 只是 IList 的众多可能实现之一。

由于代码应该是松散耦合的,依赖于抽象等等...使用连续内存(数组)来存储其值的 IList 的具体实现称为 Array 。我们不会“添加”IListArray 类,这只是错误的推理顺序; ArrayIList 实现为数组。

异常正是接口定义的。如果您了解整个接口而不仅仅是单个方法,这并不奇怪。该界面还使您有机会检查 IsFixedSize 属性并查看调用 Add 方法是否安全。

An Array is just one of many possible implementations of IList.

As code should be loosely coupled, depend on abstractions and what not... The concrete implementation of IList that uses consecutive memory (an array) to store it's values is called Array. We do not "add" IList to the Array class that's just the wrong order of reasoning; Array implements IList as an array.

The exception is exactly what the interface defines. It is not a surprise if you know the whole interface not just a single method. The interface also give you the opportunity to check the IsFixedSize property and see if it is safe to call the Add method.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文