2010-08-26 85 views
8

是否有人会描述IEnumerable和IEnumerable和数组 之间的区别以及在哪里使用它..关于它的所有信息以及如何使用它。IEnumerable和数组有什么区别?

+1

枚举= http://msdn.microsoft.com/en-us/library/9b9dty7d%28VS.80%29.aspx 数组= http://msdn.microsoft.com/en-us/图书馆/ 9b9dty7d%28VS.80%29.aspx – w69rdy 2010-08-26 16:39:51

+1

@ w69rdy - 我认为他的意思是差异IEnumerable和数组之间。 – 2010-08-26 16:48:23

回答

11

数组是指具有设置大小的对象的集合。

int[] array = [0, 1, 2]; 

这使得在情况下,您可能要访问某个项目在特定的点的集合中,因为工作地点中的每个元素的内存已经知道

array[1]; 

而且,非常有用阵列的大小可以快速计算。

IEnumerable,另一方面,基本上说,给定一个开始位置可以得到下一个值。这样的一个例子可以是一个无穷级数的数字:

public IEnumerable<int> Infinite() 
{ 
    int i = 0; 
    while(true) 
     yield return i++; 
} 

不同于阵列的枚举集合可以是任何尺寸,并且可以创建的元素,因为它们是必需的,而不是前期,这允许有力结构,并被LINQ广泛使用,以促进复杂的查询。

//This line won't do anything until you actually enumerate the created variable 
IEnumerable<int> firstTenOddNumbers = Infinite().Where(x => x % 2 == 1).Take(10); 

但是获得特定元素的唯一方法是从头开始并枚举到所需的元素。这将比从预先生成的阵列获取元素要昂贵得多。

当然你可以枚举一个数组,所以一个数组实现了IEnumerable接口。

+2

+1彻底的答案......尽管2147483647几乎是无限的。 ;) – 2010-08-26 17:05:15

+7

@djacobson它*是*无限,它只是不连续。下一个值是-2147483648 ... :) – 2010-08-26 17:11:23

+0

无限性取决于编译器设置。 – nawfal 2014-01-27 20:48:29

2

数组是数据的集合。这意味着这些物品是连续存储的,并且可以直接使用。

IEnumerable是一个描述的数据集合。它们本身不是集合​​。具体而言,这意味着收集可以逐步完成,每次一个项目。

如果将变量定义为IEnumerable类型,那么它可以引用适合该描述的任何类型的集合。

数组是可枚举的。列表,词典,集合和其他集合类型也是如此。此外,看起来并不收集的东西可以是Enumerable,例如字符串(即IEnumerable<char>),或者是由Enumerable.Range()返回的对象,它为每个步骤生成一个新项目,而实际上并没有将它保存在任何地方。

1

有一件事是,数组允许随机访问一些固定大小的内容。 IEnumerable接口顺序提供数据的位置,您可以一次从IEnumerable接口提取数据,直到数据源耗尽。

3

.NET的IEnumerable接口名称错误 - 它应该是IIterable。基本上是一个System.Collection.IEnumerable或(因为泛型)System.Collection.Generic.IEnumerable允许您使用foreach实现这些接口的对象。

(旁注:其实.NET使用鸭子类型为的foreach,所以你不需要实现这些接口 - 这是不够的,如果你提供合适的方法实现。)

数组(系统。数组)是一种序列类型(其中序列的意思是一个可迭代的数据结构,即实现IEnumerable的任何东西),但有一些重要的区别。

例如,IEnumerable可以 - 并且通常 - 延迟加载。这意味着,除非明确地遍历它,否则不会创建项目。如果你不知道这会导致奇怪的行为。 因此,IEnumerable无法告诉你它包含多少项,除非实际迭代它(System.Linq.Enumerable类中的Count扩展方法)。

一个数组有一个Length属性,并且由此我们得出了最重要的区别:一个数组,如果一个固定的(和已知的)项目序列。它还提供了一个索引器,因此您可以方便地访问它的项目,而无需实际迭代它。

为了记录,.NET中的“真实”枚举是使用enum关键字定义的类型。它们允许您在不使用幻数或字符串的情况下表达选择。当用FlagsAttribute标记时,它们也可以用作标志。

我建议你使用你的favioure搜索引擎来获得关于这些概念的更多细节 - 我的简要总结显然不是为了深入洞察这些特性。

+1

.Net中使用的术语非常好。来自http://en.wikipedia.org/wiki/Enumeration:“在数学和理论计算机科学中,一组枚举的最广泛和最抽象的定义是其所有元素的精确列表。”你所说的“真正的”枚举更适合称为“枚举类型”:http://en.wikipedia.org/wiki/Enumerated_type – Gabe 2010-09-08 07:04:09

2

阵列

一个.NET阵列是连续地存储在存储器中的多个值的集合。数组中的单个元素可以通过索引随机访问(并且这样做效率很高)。阵列的重要的成员是:

  • this[Int32 index](索引操作符)
  • Length

C#具有内置的用于阵列的支持,他们可以直接从码被初始化:

var array = new[] { 1, 2, 3, 4 }; 

数组也可以是多维的并且实现多个接口,包括IEnumerable<T>(其中T是数组的元素类型)。

的IEnumerable <Ť>

IEnumerable<T>接口定义了方法GetEnumerator()但是该方法很少直接使用。相反,foreach循环用于枚举迭代:

IEnumerable<T> enumerable = ...; 
foreach (T element in enumerable) 
    ... 

如果枚举一个数组或列表所做的所有元素的枚举过程中存在的枚举,但它也可以枚举元素在飞行中创建。 yield return构造对此非常有用。

它可以创建一个枚举的数组:

var array = enumerable.ToArray(); 

这将让来自枚举所有元素和它们在单个阵列中存储连续。

概括起来:

  • 阵列是元件的集合,该集合可以通过索引随机访问
  • 枚举是抽象以上元素的集合,可以在另一个之后向前移动访问的一个方式