为什么系统.数组类实现了illist,但不提供Add()

本文关键字:Add 数组 系统 实现 illist 为什么 | 更新日期: 2023-09-27 17:53:14

代码:

int[] myArr = { 1, 2 };
myArr.Add(3);

在构建时抛出以下错误:

错误CS1061: 'System. 'Array'没有包含'Add'的定义,也没有扩展方法'Add'接受类型为'System '的第一个参数。Array'可以找到(您是否缺少using指令或程序集引用?)

IList接口有Add()方法,但是为什么数组没有实现它?

UPDATE:我从答案中看到它确实显式地实现了它,好的,我明白了,谢谢,我最好坚持这个问题:

为什么Array实际上没有提供 Add(),或者,更好的是,为什么它必须首先实现IList ?而不是实现IList,它可以是另一个接口(例如IArray),它可以只对IList的数组成员有用-例如IsFixedSize, IsReadOnly, IndexOf()…只是一个想法。

为什么系统.数组类实现了illist,但不提供Add()

为什么Array实际上不提供Add()?

数组的大小是固定的,所以你不能添加新的元素。

维度数和每个维度的长度为在创建数组实例时建立。这些值不能在实例的生命周期内更改。https://msdn.microsoft.com/en-us/library/9b9dty7d.aspx

为什么它必须首先实现IList ?

IList的定义:表示对象的非泛型集合可以通过index单独访问。

https://msdn.microsoft.com/en-us/library/system.collections.ilist.aspx

数组通过索引访问,而illist容纳这个索引,这就是为什么Array实现了illist。

参考:为什么数组实现illist ?

是的,如果System.Array实现了IReadOnlyList或类似的接口,它应该是一个更好的设计。而IReadOnlyList<T>出现在中。Net 4.5,而System.Array从初始开始。Net 1.0 。微软尽了最大努力,通过显式接口实现隐藏了 Add

http://referencesource.microsoft.com/mscorlib/系统/array.cs 156 e066ecc4ccedf

  ...
int IList.Add(Object value)
{
    throw new NotSupportedException(Environment.GetResourceString("NotSupported_FixedSizeCollection"));
} 
  ...

所以你不能做

int[] myArr = { 1, 2 };
myArr.Add(3);

,但你可以坚持使用Add(并得到NotSupportedException抛出)通过

((IList) myArr).Add(3);

或者

if (!myArr.IsFixedSize) {
  // we have very strange array, let's try adding a value to it
  ((IList) myArr).Add(3);
}

它确实提供了Add,但是通过抛出NotSupportedException(参见MSDN),因为数组的大小是固定的。

得到编译错误的原因是因为接口是显式实现的,所以如果您想调用该方法,则需要强制转换为IList。请参阅关于显式接口实现的c#指南。

虽然实现接口的类必须实现接口的所有成员,但它可以显式地实现它们:

public class MyList<T> : IList<T>
{
    // ... shortened for simplicity
    void ICollection<T>.Add(T item) {  } // explicit implementation
}

如果你这样实现这个方法,它在MyList<T>的实例上是不可见的:

MyList<int> list = new MyList<int>();
list.Add(5); // would NOT compile
((IList<int>)list).Add(5); // can be compiled

如果你有一个int[]你可以这样做:

int[] array = new int[0];
((IList<int>)array).Add(5);

它将编译,但在运行时会抛出NotSupportedException,因为数组有固定的大小,并且您不能添加新元素到数组中,因为它的大小是在初始化时确定的(new int[0])。

系统。数组类实现了illist,但不提供Add()

当然可以通过显式实现(实现接口而不实现某些成员是不可能的)。

为什么数组实现IList ?

嗯,主要是表示它支持索引器。

但实际上数组实现了IList的一种有效用法。IList接口有一个名为IsFixedSize的属性,根据文档

获取一个值,该值指示illist是否具有固定大小。

固定大小的集合不允许在创建后添加或删除元素,但允许修改已有的元素。

因此数组实现返回IsFixedSize = true并在Add, Insert, RemoveRemoveAt方法中抛出NotSupportedException

根据msdn:

IList.Add(对象)

调用这个方法总是会抛出NotSupportedExceptionexception。

数组类-参见显式接口实现部分

Array有这个方法。要调用这个方法,应该显式地强制转换为IList。这个方法不能被调用,因为数组的大小是固定的,不能动态改变。

IList在三个不同的类别中实现:

  • 只读的
  • 变量大小
  • 固定大小

显然Array类型是IList的固定大小实现。不能从Array访问Add()方法的原因是因为该方法是显式实现的:

public class A : IList {
    public void IList.Add(object o){
         ...
    }
}

这意味着在您能够使用Add方法之前,您需要将您的数组强制转换为IList(即使它会抛出一个不支持的异常)。

你可能会说这是一个糟糕的设计,很多人会同意你的观点。

阅读更多显式定义的接口:https://msdn.microsoft.com/en-us/library/aa288461 (v = vs.71) . aspx