为什么系统.数组类实现了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()
…只是一个想法。
为什么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
, Remove
和RemoveAt
方法中抛出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