所以IEnumerable
不保证订单。
这是否意味着如果你做myEnumerable.Skip(5)
你不能(除非你.ToList()
或以前做过)保证将返回什么?
答案 0 :(得分:5)
一旦对象由IEnumerator
产生,他们做就会有订单。首先出现一些项目,然后出现一些项目,等等。对于某些特定的实现,订单可能有意义,对于其他项目,它可能是任意的,但仍然存在一些顺序。 Skip
实施很简单;它得到了许多物品而没有产生它们,然后得到其余的并产生它们。跳过的项目是否意味着特别是任何调用该方法的人的责任。
调用ToList
永远不会更改序列中项目的顺序,因此在调用Skip
之前添加此类调用不会改变任何内容。另一方面,对OrderBy
的调用将导致更改的顺序,可能从无意义的顺序到有意义的顺序。这并不是说它是必需的,只是它在某些情况下可以成为一种有用的工具。
答案 1 :(得分:3)
任何特定IEnumerable<T>
是否保证特定排序取决于
数组将以明显的顺序(从x[0]
到x[n]
枚举其内容。)同样为List<T>
,它本质上是一个可调整长度的数组。当然,实际[链接]列表只能按顺序枚举。
Dictionary<K,V>
,HashSet<T>
,二叉树等的枚举顺序取决于添加对象的顺序。将具有不同排序的相同值集合添加到二叉树中,并且由此构造的树的结构将变化(当然,退化情况是当按顺序添加对象时,在这种情况下,树结构折叠成[有序] ]链表。
话虽如此,IEnumerable<T>
的任何特定实例,除非对基础集合进行任何修改,否则每次枚举时都会产生相同的值序列。当然,这假设是接口的合理实现。如果接口通过随机随机播放来枚举集合,当然,所有赌注都会关闭。
如果生成的项目的实际顺序很重要,则需要
答案 2 :(得分:0)
如果您使用Skip(x)
,则会忽略第一个x
元素,之后的所有内容都将以新的IEnumerable<T>
返回。界面不保证它会保留顺序,但实际上它确实如此。无论何时操作IEnumerable<T>
,它实际上都会以线性方式通过相同的列表。例如,如果你逐行读取文件和IEnumerable<T>
,那么这些行的顺序与它们在文件中的顺序相同(假设你没有使用排序方法)。即使您使用Where
或其他方法过滤结果,订单仍会保留。您唯一需要担心的是实现IEnumerable<T>
的自定义集合。 .NET中的集合将按照您的预期运行。
答案 3 :(得分:0)
IEnumerable是一个接口。因此,界面无法保证订单。但是,如果您有一个实现该接口的实际对象,则该对象可能(并且通常会)保证订单。