Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么System.Array类实现IList但不提供Add()_C#_List_System.array - Fatal编程技术网

C# 为什么System.Array类实现IList但不提供Add()

C# 为什么System.Array类实现IList但不提供Add(),c#,list,system.array,C#,List,System.array,此代码: int[] myArr = { 1, 2 }; myArr.Add(3); 在生成时引发以下错误: 错误CS1061:“System.Array”不包含“Add”的定义,并且找不到接受“System.Array”类型的第一个参数的扩展方法“Add”(是否缺少using指令或程序集引用?) IList接口有Add()方法,但是为什么数组没有实现它呢 更新:我从答案中看到它确实明确地实现了它,好的,我明白了,谢谢,我最好还是坚持这个问题: 为什么Array实际上没有提供Add(),或者更

此代码:

int[] myArr = { 1, 2 };
myArr.Add(3);
在生成时引发以下错误:

错误CS1061:“System.Array”不包含“Add”的定义,并且找不到接受“System.Array”类型的第一个参数的扩展方法“Add”(是否缺少using指令或程序集引用?)

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

更新:我从答案中看到它确实明确地实现了它,好的,我明白了,谢谢,我最好还是坚持这个问题:


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

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

数组具有固定大小,因此无法添加新元素

尺寸的数量和每个尺寸的长度如下所示 在创建阵列实例时建立。这些值不能被忽略 在实例的生存期内更改。

为什么首先必须实施IList?

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

数组由索引访问,IList容纳此索引,这就是数组实现IList的原因


仅供参考:

它确实提供了Add,但是抛出了一个
NotSupportedException
(请参阅),因为数组的大小是固定的


相反,出现编译错误的原因是接口是显式实现的,因此如果要调用该方法,则需要强制转换到
IList
。请参阅本C#指南。

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

public class MyList<T> : IList<T>
{
    // ... shortened for simplicity
    void ICollection<T>.Add(T item) {  } // explicit implementation
}
public class A : IList {
    public void IList.Add(object o){
         ...
    }
}
它将进行编译,但在运行时将抛出一个
NotSupportedException
,因为数组具有固定大小,并且不能向数组中添加新元素,因为它的大小是在初始化时确定的(
new int[0]
)。

根据msdn:

添加(对象)

调用此方法始终会引发NotSupportedExceptionexception

-参见显式接口实现部分


数组
具有此方法。要调用此方法,应显式强制转换为
IList
。无法调用此方法,因为数组具有固定大小,并且此大小不能动态更改。

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

  • 只读
  • 可变尺寸
  • 固定尺寸
显然,
Array
类型是
IList
的固定大小实现。 无法从
数组访问
Add()
方法的原因是该方法是显式实现的:

public class MyList<T> : IList<T>
{
    // ... shortened for simplicity
    void ICollection<T>.Add(T item) {  } // explicit implementation
}
public class A : IList {
    public void IList.Add(object o){
         ...
    }
}
这意味着您需要将数组强制转换为
IList
,然后才能使用
Add
方法(即使它会引发不受支持的异常)

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

阅读有关显式定义接口的更多信息:

数组类实现IList,但不提供Add()

当然,它是通过显式实现实现的(无法实现接口,也无法实现某些成员)

阵列为何实现IList

那么主要是表示它支持indexer

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

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

然后

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


因此,数组实现返回
IsFixedSize=true
并在
Add
Insert
Remove
RemoveAt
方法中抛出
NotSupportedException
,如果
System.Array
实现了
IReadOnlyList
或类似的接口,那么它应该是一个更好的设计。但是,
IReadOnlyList
出现在.net4.5中,而
System.Array
保留在.net1.0的初始值。微软IMHO尽了最大努力,通过显式界面实现隐藏了
Add

所以你不能这么做

int[] myArr = { 1, 2 };

myArr.Add(3);
但是您可以坚持使用
Add
(并通过

甚至

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

如果将其转换为
IList
,则可以调用
Add
(类可以实现一些接口,这意味着您在将其视为该接口时只能访问(所有)接口方法)。不过你会失望的。数组有一个固定的大小。那么为什么该语言不从数组类签名中删除:IList呢?它没有。数组实现了
IList
-但是如果你想将它用作
IList
,你必须将它转换成那种类型的变量。@Damien_不信者,很抱歉我更正了这个问题,我的意思是为什么它不删除它!这回答了你的问题吗?那么为什么它要实现IList(它有Add)?@cnom您可以在这里看到:
Add()
不是
ICollection
@haim770的一部分是的:您是对的。我提到了非泛型版本,它(明确地)通过问题中的
Array
实现
((IList) myArr).Add(3);
if (!myArr.IsFixedSize) {
  // we have very strange array, let's try adding a value to it
  ((IList) myArr).Add(3);
}