2

所以IEnumerable不保证顺序。

这是否意味着如果你这样做,myEnumerable.Skip(5)你不能(除非你这样做.ToList()或之前)保证会退还什么?

4

4 回答 4

5

一旦对象被 an 产生,IEnumerator它们确实有一个顺序。有一些项目首先出现,一些项目随后出现,依此类推。对于某些特定的实现,顺序可能有意义,对于其他实现,它可能是任意的,但仍然有一些顺序。Skip实现很简单;它得到了许多项目而不产生它们,然后得到其余的并产生它们。跳过的项目是否有任何特殊意义是调用该方法的人的责任。

调用ToList永远不会改变序列中项目的顺序,所以在调用之前添加这样的调用Skip不会改变任何东西。OrderBy另一方面,调用将导致更改顺序,可能从无意义的顺序变为有意义的顺序。这并不是说它是必需的,只是在某些情况下它可以成为有用的工具。

于 2013-09-19T16:56:37.883 回答
3

任何特定的是否保证特定的排序IEnumerable<T>取决于

  • 该特定实现是如何完成的,以及如何完成的
  • 底层集合/类的语义。

数组将以明显的顺序(从x[0]x[n])枚举其内容。a 同上List<T>,它本质上是一个长度可调的数组。当然,实际的 [链接] 列表只能按顺序枚举。

Dictionary<K,V>, , 二叉树等的枚举顺序HashSet<T>取决于添加对象的顺序。将具有不同顺序的相同值集合添加到二叉树中,由此构建的树的结构会有所不同(退化的情况,当然是当对象按顺序添加时,在这种情况下,树结构会折叠成 [ordered ] 链表。

话虽IEnumerable<T>如此,除非对基础集合进行任何修改,否则 , 的任何特定实例在每次枚举时都会产生相同的值序列。当然,这假设接口的合理实现。如果界面通过随机洗牌来枚举集合,当然,所有的赌注都是关闭的。

如果生产的物品的实际顺序很重要,您需要

  • 使用具有所需语义的集合,或
  • 通过对集合或枚举进行排序来强制执行所需的排序。
于 2013-09-19T17:37:04.517 回答
0

如果使用Skip(x),第一个x元素将被忽略,之后的所有内容都将返回一个新的IEnumerable<T>. 该接口不保证它会保持顺序,但实际上它确实如此。任何时候你对它进行操作时,IEnumerable<T>它实际上都会以线性方式通过同一个列表。例如,如果您逐行读取文件,并且IEnumerable<T>这些行将始终与它们在文件中的顺序相同(假设您不使用排序方法)。即使您使用某种Where或其他方法来过滤结果,仍然会保留顺序。您唯一需要担心的是实现IEnumerable<T>. .NET 中的集合将按照您期望的方式运行。

于 2013-09-19T16:59:22.617 回答
0

IEnumerable 是一个接口。因此,接口不能保证顺序。但是,如果您有一个实现该接口的实际对象,则该对象可能(并且通常会)保证顺序。

于 2013-09-19T17:01:33.217 回答