我试图理解C#中的IEnumerable
接口。正如MSDN中所述
IEnumerable
公开了一个枚举器,它支持对非泛型集合的简单迭代。这很简单。当我们有一个实现此接口的集合时,我们得到一个枚举器,它实现了IEnumerator
接口,(http://msdn.microsoft.com/en-us/library/system.collections.ienumerable.getenumerator(v=vs.110).aspx),并且使用这个枚举器,我们可以迭代集合中的所有元素如下所示:
foreach(var item in items)
{
// code goes here
}
在上面的代码片段中,items
是一个实现IEnumerable
接口的集合。这是可能的,因为枚举器有一个名为Current
的属性,它具有集合的当前元素和枚举器使用的方法MoveNext
,以移动到下一个元素。最后但并非最不重要的是,它有一个名为Reset
的方法,它将枚举数设置为其初始位置,该位置位于集合中的第一个元素之前,如MSDN中所述。
我们有以下代码片段:
int[] array = new int[10] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
IEnumerable<int> numbers = array;
foreach (var number in numbers)
{
Console.WriteLine(number);
}
在上面的代码片段中,我们初始化一个整数数组,然后我们定义一个指向数组的IEnumerable
类型。由于numbers
实现了IEnumerable
,我们可以使用上面的foreach
来迭代它的元素。
我认为幕后的编译器发出一些代码,当我们定义numbers
然后尝试迭代它的元素时。实际上我发现Array
实现了IEnumerable<T>
。
我的问题是每次我们定义一个数组,因为数组是一个实现IEnumerable
和IEnumerator
的对象,相应的方法是由编译器实现的吗?
提前感谢您的帮助!
答案 0 :(得分:2)
你的问题,
我的问题是每次我们定义一个数组,因为数组是一个实现
IEnumerable
和IEnumerator
的对象,相应的方法是由编译器实现的吗?
根据备注部分下的MSDN documentation明确提及,
从.NET Framework 2.0开始,Array类实现
System.Collections.Generic.IList<T>
,System.Collections.Generic.ICollection<T>
和System.Collections.Generic.IEnumerable<T>
通用接口。 这些实现在运行时提供给数组,因此文档构建工具不可见。因此,通用接口不会出现在Array
类的声明语法中,并且没有可通过将数组转换为通用接口类型(显式接口实现)来访问的接口成员的参考主题。将数组转换为其中一个接口时要注意的关键是添加,插入或删除元素的成员抛出NotSupportedException
。
是的,编译器在运行时将实现提供给数组。
编辑您的评论中的问题
所有非泛型集合都会发生这种情况吗?
阅读帖子后,
在查看了所有Collections之后,我发现ArrayList
,BitArray
等都是集合,但没有实现任何通用接口。
如果我错了,请纠正我我不认为在运行时会提供所有Collection
的实现。