IEnumerable和数组有什么区别?
是否有人会描述IEnumerable以及IEnumerable和数组之间的区别以及在何处使用它…所有关于它的信息以及如何使用它。
数组是具有设置大小的对象的集合。
int[] array = [0, 1, 2];
这使得它在您可能想要访问集合中特定位置的项目的情况下非常有用,因为每个元素的内存中的位置已知
array[1];
此外,可以快速计算arrays的大小。
另一方面,IEnumerable基本上说,给定一个起始位置,可以获得下一个值。 这方面的一个例子可能是一系列无数的数字:
public IEnumerable Infinite() { int i = 0; while(true) yield return i++; }
与数组不同,可枚举集合可以是任何大小,并且可以在需要时创建元素,而不是在前面,这允许强大的构造,并且LINQ广泛使用它来促进复杂查询。
//This line won't do anything until you actually enumerate the created variable IEnumerable firstTenOddNumbers = Infinite().Where(x => x % 2 == 1).Take(10);
但是,获取特定元素的唯一方法是从头开始并枚举到您想要的那个元素。 这比从预生成的数组中获取元素要昂贵得多。
当然,您可以通过数组枚举,因此数组实现IEnumerable接口。
.NET的IEnumerable接口名称错误 – 它应该是IIterable。 基本上是System.Collection.IEnumerable或(自generics)System.Collection.Generic.IEnumerable允许您在实现这些接口的对象上使用foreach。
(旁注:实际上.NET正在为foreach使用duck typing,所以你不需要实现这些接口 – 如果你提供合适的方法实现就足够了。)
数组(System.Array)是一种序列(其中序列我指的是一个可迭代的数据结构,即实现IEnumerable的任何东西),但有一些重要的区别。
例如,IEnumerable可以 – 并且经常 – 延迟加载。 这意味着在您明确迭代它之前,将不会创建项目。 如果您不了解它,这可能会导致奇怪的行为。 因此,IEnumerable无法告诉您它包含多少项,直到您实际迭代它(System.Linq.Enumerable类中的Count扩展方法)。
一个数组有一个Length属性,有了这个,我们得到了最重要的区别:一个数组,如果是一系列固定(和已知)项。 它还提供了一个索引器,因此您可以方便地访问其项目而无需实际迭代它。
仅仅为了记录,.NET中的“真实”枚举是使用enum关键字定义的类型。 它们允许您在不使用幻数或字符串的情况下表达选择。 当使用FlagsAttribute标记时,它们也可以用作标志。
我建议您使用您喜爱的搜索引擎来获取有关这些概念的更多详细信息 – 我的简要摘要显然并非旨在深入了解这些function。
Array是一组数据。 这意味着这些商品是连续存储的,并且可以直接加入。
IEnumerable是对数据集合的描述 。 它们本身不是collections品。 具体来说,这意味着可以逐步执行集合,一次一个项目。
如果将变量定义为IEnumerable类型,则它可以引用适合该描述的任何类型的集合。
数组是可枚举的。 Lists,Dictionaries,Sets和其他集合类型也是如此。 此外,看起来不是集合的东西可以是Enumerable,例如字符串( IEnumerable
),或Enumerable.Range()
返回的对象,它为每个步骤生成一个新项目,而不是实际上把它拿到了任
数组
.Net数组是连续存储在内存中的多个值的集合。 可以通过索引随机访问数组中的各个元素(这样做非常有效)。 数组的重要成员是:
-
this[Int32 index]
(索引运算符) -
Length
C#内置了对数组的支持,可以直接从代码初始化它们:
var array = new[] { 1, 2, 3, 4 };
数组也可以是多维的,并实现几个接口,包括IEnumerable
(其中T
是数组的元素类型)。
的IEnumerable
IEnumerable
接口定义了方法GetEnumerator()
但该方法很少直接使用。 相反, foreach
循环用于迭代枚举:
IEnumerable enumerable = ...; foreach (T element in enumerable) ...
如果枚举是在数组或列表上完成的,枚举中的所有元素都存在于枚举期间,但也可以枚举动态创建的元素。 yield return
构造对此非常有用。
可以从枚举中创建一个数组:
var array = enumerable.ToArray();
这将获取枚举中的所有元素并将它们连续存储在单个数组中。
把它们加起来:
- 数组是可以通过索引随机访问的元素集合
- 枚举是对一组元素的抽象,这些元素可以以前向移动的方式一个接一个地访问
有一点是Arrays允许随机访问一些固定大小的内容。 IEnumerable接口按顺序提供数据的位置,您可以一次从IEnumerable中提取数据,直到数据源耗尽为止。