了解C#</t>中的IEnumerable <t>

时间:2013-12-12 12:09:20

标签: c# .net collections ienumerable

我试图理解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>

我的问题是每次我们定义一个数组,因为数组是一个实现IEnumerableIEnumerator的对象,相应的方法是由编译器实现的吗?

提前感谢您的帮助!

1 个答案:

答案 0 :(得分:2)

你的问题,

  

我的问题是每次我们定义一个数组,因为数组是一个实现IEnumerableIEnumerator的对象,相应的方法是由编译器实现的吗?

根据备注部分下的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之后,我发现ArrayListBitArray等都是集合,但没有实现任何通用接口。

如果我错了,请纠正我我不认为在运行时会提供所有Collection的实现。