FOREACH返回的对象的顺序是否稳定?

时间:2008-10-03 14:19:41

标签: c# .net collections foreach ienumerable

假设同一个集合上的两个itterations将以相同的顺序返回对象是否安全?显然,假设该集合没有另外改变。

8 个答案:

答案 0 :(得分:25)

这取决于集合类型。对于大多数收藏品,答案是“是”。

但是,这不能保证。集合类型的文档应该指定它是否存在,但是大多数情况下,该细节通常都是过度查看的。但是,如果它不稳定,如果文档没有提及,那将是一个巨大的疏忽。

答案 1 :(得分:15)

简短回答 - 是的。

显然,集合中项目的顺序可能与插入时的顺序不同,具体取决于集合的类型(例如字典)。

但是每次使用foreach循环遍历单个未修改的集合时,您将获得相同的结果。

答案 2 :(得分:10)

除非您了解正在迭代的类的具体实现,否则您无法保证这一点。

具有已定义元素顺序的集合(例如List<T>)将以稳定的顺序枚举。

对于对象状态未发生变化的集合,元素很可能以相同的顺序返回,例如: Dictionary<K,V>,虽然规范不能保证。

作为不存在这种情况的示例,您可以想象一个基于散列表的字典实现,它以异步方式压缩或调整表的大小。这样的实现不能保证稳定的迭代顺序。

答案 3 :(得分:6)

虽然对于所有内置集合以及可能任何理智的集合类,答案都是“是”,但文档没有为IEnumerable制定任何约束。因此,没有任何东西告诉我们每次迭代必须是稳定的。

我可以想象以下用例:

foreach (int i in new Shuffler(1, 2, 3, 4, 5, 6, 7, 8, 9))
    Console.WriteLine(i);

这可能会被实现为一个为每次迭代产生不同排序的类。

所以 - 如果你还想考虑奇怪的边界情况,答案应该是“没有”。

答案 4 :(得分:3)

虽然通常情况下,元素将以相同的顺序返回,但绝对不能保证。它完全依赖于集合类的内部实现。

我可以看到一个集合类的例子,它专门用于以随机顺序返回元素,例如。

简而言之,除非您知道集合类的内部实现,否则不会假设有关该订单的任何内容。

答案 5 :(得分:2)

Linq为此目的定义了IOrderedEnumerable接口。

答案 6 :(得分:1)

重新“未修改”(NM的回复) - 请注意许多像Dictionary这样的复杂容器不保证保留顺序。有时添加项目会使其显示在最后(给人的印象是保留订单),有时它会导致内部存储桶重新组织,从而产生完全不同的顺序。

像SortedList&lt;,&gt;这样的东西等显然有自己的规则。

答案 7 :(得分:0)

我想说,对于大多数收藏品来说,假设这是安全的。某个集合可能以非确定性的方式实现调查器,但这可能不会发生......