为什么 System.Array class 实现了 IList 但不提供 Add()
Why System.Array class implements IList but does not provide Add()
此代码:
int[] myArr = { 1, 2 };
myArr.Add(3);
在构建时抛出以下错误:
error CS1061: 'System.Array' does not contain a definition for 'Add' and no extension method 'Add' accepting a first argument of type 'System.Array' could be found (are you missing a using directive or an assembly reference?)
IList
接口有Add()
方法,为什么Array没有实现?
更新:我从答案中看到它确实明确地实现了它,好的,我明白了,谢谢,我应该更好地坚持这个问题:
为什么 Array
实际上 没有提供 Add()
,或者,更好的是,为什么它首先要实现 IList
?它可以是另一个接口(例如 IArray
),而不是实现 IList
,它可能只对 IList
的数组成员有用 - 例如IsFixedSize
、IsReadOnly
、IndexOf()
...只是一个想法。
为什么Array实际上没有提供Add()?
数组具有固定大小,因此您不能添加新元素。
The number of dimensions and the length of each dimension are
established when the array instance is created. These values can't be
changed during the lifetime of the instance.
https://msdn.microsoft.com/en-us/library/9b9dty7d.aspx
为什么它首先要实现 IList?
Definition of IList: Represents a non-generic collection of objects
that can be individually accessed by index.
https://msdn.microsoft.com/en-us/library/system.collections.ilist.aspx
Array 是通过索引访问的,而 IList 容纳了这个索引,这就是 Array 实现 IList 的原因。
供参考:Why array implements IList?
它确实提供了Add,但是通过抛出一个NotSupportedException
(参见MSDN),因为数组的大小是固定的。
之所以会出现编译错误,是因为接口是显式实现的,所以如果要调用需要强制转换为 IList
的方法。请参阅有关 explicit interface implementation.
的 C# 指南
虽然实现接口的 class 必须实现接口的所有成员,但它可以显式实现它们:
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
因为 数组有固定大小 而你不能 add数组的新元素,因为它的大小在初始化时确定 (new int[0]
)。
根据msdn:
IList.Add(Object)
Calling this method always throws a NotSupportedExceptionexception.
Array Class - 参见显式接口实现部分
Array
有这个方法。要调用此方法,您应该显式转换为 IList
。无法调用此方法,因为数组的大小是固定的,无法动态更改。
IList
在三个不同的类别中实现:
- 只读
- 可变大小
- 固定尺寸
显然 Array
类型是 IList
的固定大小实现。
您无法从 Array
访问 Add()
方法的原因是因为该方法是显式实现的:
public class A : IList {
public void IList.Add(object o){
...
}
}
这意味着您需要先将数组转换为 IList
,然后才能使用 Add
方法(即使它会抛出不受支持的异常)。
你可能会说这是一个糟糕的设计,很多人会同意你的看法。
阅读有关显式定义接口的更多信息:
https://msdn.microsoft.com/en-us/library/aa288461(v=vs.71).aspx
System.Array class implements IList but does not provide Add()
当然是通过显式实现实现的(没有办法实现接口而不实现某些成员)。
Why the array implements IList
?
嗯,主要是说明它支持indexer。
但实际上数组实现了一种有效的 IList
用法。 IList
接口有一个名为 IsFixedSize
的 属性,根据文档
Gets a value indicating whether the IList has a fixed size.
然后
A collection with a fixed size does not allow the addition or removal of elements after the collection is created, but it allows the modification of existing elements.
所以数组实现 returns IsFixedSize = true
并在 Add
、Insert
、Remove
和 RemoveAt
方法中抛出 NotSupportedException
.
是的,如果 System.Array
实现了 IReadOnlyList
或类似的接口,似乎应该是一个更好的设计。然而,IReadOnlyList<T>
出现在.Net 4.5中,而System.Array
保留在最初的.Net 1.0中。微软,恕我直言,尽了最大努力,并通过 显式接口实现
隐藏 Add
http://referencesource.microsoft.com/#mscorlib/system/array.cs,156e066ecc4ccedf
...
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);
}
此代码:
int[] myArr = { 1, 2 };
myArr.Add(3);
在构建时抛出以下错误:
error CS1061: 'System.Array' does not contain a definition for 'Add' and no extension method 'Add' accepting a first argument of type 'System.Array' could be found (are you missing a using directive or an assembly reference?)
IList
接口有Add()
方法,为什么Array没有实现?
更新:我从答案中看到它确实明确地实现了它,好的,我明白了,谢谢,我应该更好地坚持这个问题:
为什么 Array
实际上 没有提供 Add()
,或者,更好的是,为什么它首先要实现 IList
?它可以是另一个接口(例如 IArray
),而不是实现 IList
,它可能只对 IList
的数组成员有用 - 例如IsFixedSize
、IsReadOnly
、IndexOf()
...只是一个想法。
为什么Array实际上没有提供Add()?
数组具有固定大小,因此您不能添加新元素。
The number of dimensions and the length of each dimension are established when the array instance is created. These values can't be changed during the lifetime of the instance. https://msdn.microsoft.com/en-us/library/9b9dty7d.aspx
为什么它首先要实现 IList?
Definition of IList: Represents a non-generic collection of objects that can be individually accessed by index.
https://msdn.microsoft.com/en-us/library/system.collections.ilist.aspx
Array 是通过索引访问的,而 IList 容纳了这个索引,这就是 Array 实现 IList 的原因。
供参考:Why array implements IList?
它确实提供了Add,但是通过抛出一个NotSupportedException
(参见MSDN),因为数组的大小是固定的。
之所以会出现编译错误,是因为接口是显式实现的,所以如果要调用需要强制转换为 IList
的方法。请参阅有关 explicit interface implementation.
虽然实现接口的 class 必须实现接口的所有成员,但它可以显式实现它们:
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
因为 数组有固定大小 而你不能 add数组的新元素,因为它的大小在初始化时确定 (new int[0]
)。
根据msdn:
IList.Add(Object)
Calling this method always throws a NotSupportedExceptionexception.
Array Class - 参见显式接口实现部分
Array
有这个方法。要调用此方法,您应该显式转换为 IList
。无法调用此方法,因为数组的大小是固定的,无法动态更改。
IList
在三个不同的类别中实现:
- 只读
- 可变大小
- 固定尺寸
显然 Array
类型是 IList
的固定大小实现。
您无法从 Array
访问 Add()
方法的原因是因为该方法是显式实现的:
public class A : IList {
public void IList.Add(object o){
...
}
}
这意味着您需要先将数组转换为 IList
,然后才能使用 Add
方法(即使它会抛出不受支持的异常)。
你可能会说这是一个糟糕的设计,很多人会同意你的看法。
阅读有关显式定义接口的更多信息: https://msdn.microsoft.com/en-us/library/aa288461(v=vs.71).aspx
System.Array class implements IList but does not provide Add()
当然是通过显式实现实现的(没有办法实现接口而不实现某些成员)。
Why the array implements
IList
?
嗯,主要是说明它支持indexer。
但实际上数组实现了一种有效的 IList
用法。 IList
接口有一个名为 IsFixedSize
的 属性,根据文档
Gets a value indicating whether the IList has a fixed size.
然后
A collection with a fixed size does not allow the addition or removal of elements after the collection is created, but it allows the modification of existing elements.
所以数组实现 returns IsFixedSize = true
并在 Add
、Insert
、Remove
和 RemoveAt
方法中抛出 NotSupportedException
.
是的,如果 System.Array
实现了 IReadOnlyList
或类似的接口,似乎应该是一个更好的设计。然而,IReadOnlyList<T>
出现在.Net 4.5中,而System.Array
保留在最初的.Net 1.0中。微软,恕我直言,尽了最大努力,并通过 显式接口实现
Add
http://referencesource.microsoft.com/#mscorlib/system/array.cs,156e066ecc4ccedf
...
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);
}