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

C# FOREACH返回的对象顺序是否稳定?,c#,.net,collections,foreach,ienumerable,C#,.net,Collections,Foreach,Ienumerable,假设同一集合上的两个对象将以相同的顺序返回对象,安全吗?显然,假设集合没有被更改。简短回答-是 但是,显然,集合中项目的顺序可能与插入的顺序不完全相同,这取决于集合的类型(例如,字典) 但是,每次使用foreach循环迭代单个未修改的集合时,都会得到相同的结果。这取决于集合类型。对于大多数收藏,答案是“是” 然而,这并不能保证。集合类型的文档应该指定是否有,但与大多数文档一样,该细节通常被忽略了。然而,如果它不稳定,如果文档没有提到这一点,那将是一个巨大的疏忽。我要说的是,对于大多数收集来说,假

假设同一集合上的两个对象将以相同的顺序返回对象,安全吗?显然,假设集合没有被更改。

简短回答-是

但是,显然,集合中项目的顺序可能与插入的顺序不完全相同,这取决于集合的类型(例如,字典)


但是,每次使用foreach循环迭代单个未修改的集合时,都会得到相同的结果。

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


然而,这并不能保证。集合类型的文档应该指定是否有,但与大多数文档一样,该细节通常被忽略了。然而,如果它不稳定,如果文档没有提到这一点,那将是一个巨大的疏忽。

我要说的是,对于大多数收集来说,假设这一点是安全的。某个集合可以以不确定的方式实现枚举器,这并不超出可能性范围,但这可能不会发生…

而对于所有内置集合和可能存在的任何sane集合类,答案都是“是”,该文档没有为
IEnumerable
制定任何约束。因此,没有任何东西告诉我们每个迭代都必须是稳定的

我可以想象以下用例:

foreach (int i in new Shuffler(1, 2, 3, 4, 5, 6, 7, 8, 9))
    Console.WriteLine(i);
这很可能被实现为一个类,为每个迭代生成不同的顺序


这样,如果你还想考虑奇怪的边界情况,答案应该是“<强>否/强”。

< P>典型地,元素将按相同的顺序返回,绝对没有保证。这完全取决于collection类的内部实现

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


简而言之,除非您知道collection类的内部实现,否则不要假设任何有关顺序的内容。

除非您知道要迭代的类的具体实现,否则无法保证这一点

具有已定义元素顺序(例如,
列表
)的集合将以稳定顺序枚举

对于对象状态不变的集合,元素很可能会以相同的顺序返回,例如
字典
,尽管规范没有保证这一点

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

Re“unmodified”(NM的回复)——请注意,许多复杂的容器(如Dictionary)不能保证保持顺序。有时添加项目会使其最后出现(给人留下保留订单的印象),有时会导致内部存储桶重新组织,给出完全不同的订单


SortedList等显然有自己的规则。

Linq为此定义了接口。

hmmmm。。。看来我们俩做了同样的事。写了一句话,贴了出来,然后马上编辑出来详细阐述。我认为你的答案比我的更合适,希望OP会将其标记为最终答案。当然,这似乎赢得了公众投票:)把它作为最终答案的问题当然是,它不准确@史蒂夫·摩根(Steve Morgan)说,对大多数收藏品来说,“是的”,这取决于收藏品的类型。我认为你的观点是正确的,但是说它不准确。。。我不确定。我认为这是不对的。目前,一个字典可以被多次枚举,并将以相同的顺序返回项目,但文档中提到值的顺序未定义,这意味着它可能会发生变化——例如在下一个.NET版本中——如果您依赖未记录的行为,代码就会中断。详细说明:一个
列表
承诺项目按特定顺序返回,您可以依赖该行为。例如,一本
字典
没有做出任何这样的承诺,因此这种行为可以随时改变。嗯,詹姆斯改变了他的答案吗?当我写我的作品时,它仍然是原创的-/订单不一致的一个很好的例子!这取决于您是否喜欢“可能”会起作用的代码。就我个人而言,我更喜欢自信!