作为一名新的.NET 3.5程序员,我开始学习LINQ,并且发现了一些我之前没有注意到的基本内容:
本书声称每个数组都实现IEnumerable<T>
(显然,否则我们无法在数组上使用LINQ到对象......)。当我看到这个时,我心里想,我从未真正考虑过这个问题,我问自己所有的数组都实现了什么 - 所以我检查了一下
System.Array
使用对象浏览器(因为它是CLR中每个数组的基类),令我惊讶的是,它没有实现IEnumerable<T>
。
所以我的问题是:定义在哪里?我的意思是,我怎么能准确地告诉每个阵列实现哪些接口?
答案 0 :(得分:69)
来自documentation(强调我的):
[...] Array类实现
System.Collections.Generic.IList<T>
,System.Collections.Generic.ICollection<T>
和System.Collections.Generic.IEnumerable<T>
通用接口。 这些实现在运行时提供给数组,因此文档构建工具不可见。
编辑:正如Jb Evain在评论中指出的那样,只有向量(一维数组)实现了通用接口。至于为什么多维数组没有实现泛型接口,我不太确定,因为它们实现了非泛型对应物(参见下面的类声明)。
System.Array
类(即每个数组)也实现了这些非通用接口:
public abstract class Array : ICloneable, IList, ICollection, IEnumerable, IStructuralComparable, IStructuralEquatable
答案 1 :(得分:62)
您可以使用小代码片段来凭经验找到问题的答案:
foreach (var type in (new int[0]).GetType().GetInterfaces())
Console.WriteLine(type);
运行上面的代码段将导致以下输出(在.NET 4.0上):
System.ICloneable
System.Collections.IList
System.Collections.ICollection
System.Collections.IEnumerable
System.Collections.IStructuralComparable
System.Collections.IStructuralEquatable
System.Collections.Generic.IList`1[System.Int32]
System.Collections.Generic.ICollection`1[System.Int32]
System.Collections.Generic.IEnumerable`1[System.Int32]
(`1
表示<T>
)
答案 2 :(得分:53)
从 .NET 4.5开始,数组也实现了接口System.Collections.Generic.IReadOnlyList<T>
和System.Collections.Generic.IReadOnlyCollection<T>
。
因此,在使用.NET 4.5时,数组实现的完整接口列表(使用Hosam Aly's answer中提供的方法获得):
System.Collections.IList
System.Collections.ICollection
System.Collections.IEnumerable
System.Collections.IStructuralComparable
System.Collections.IStructuralEquatable
System.Collections.Generic.IList`1[System.Int32]
System.Collections.Generic.ICollection`1[System.Int32]
System.Collections.Generic.IEnumerable`1[System.Int32]
System.Collections.Generic.IReadOnlyList`1[System.Int32]
System.Collections.Generic.IReadOnlyCollection`1[System.Int32]
奇怪的是,似乎忘记更新documentation on MSDN以提及这两个界面。
答案 3 :(得分:1)
小心地在数组接口上,他们可能会实现它们,但实际上它们并没有真正做到这一点......在下面的代码中找一个懒人:
var x = new int[] { 1, 2, 3, 4, 5 };
var y = x as IList<int>;
Console.WriteLine("The IList:" + string.Join(",", y));
try
{
y.RemoveAt(1);
}
catch (Exception e)
{
Console.WriteLine(e);
}
Console.WriteLine(string.Join(",", y));
它产生以下输出: result
所以解析工作但不支持从固定长度集合角度来看是正确的,但是如果你真的认为它是一个列表那就错了。来自SOLID的Liskov原则:(。
快速测试this会有所帮助。
答案 4 :(得分:0)
我在数组的IList<T>, ICollection<T>, IEnumerable<T>
嵌套类中找到了SZArrayHelper
的实现。
但我必须警告你 - 你会发现更多问题......
之后我只得到一个 - there_is_no_array;)