19

假设对同一个集合的两次迭代将以相同的顺序返回对象是否安全?显然,假设该集合没有以其他方式改变。

4

8 回答 8

25

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

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

于 2008-10-03T14:21:58.667 回答
15

简短的回答 - 是的。

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

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

于 2008-10-03T14:21:27.217 回答
10

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

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

对于对象状态不改变的集合,元素很可能会以相同的顺序返回,例如Dictionary<K,V>,尽管规范不保证这一点。

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

于 2008-10-03T14:30:24.140 回答
6

虽然对于所有内置集合以及可能存在的任何健全的集合类,答案都是“是”,但文档没有为IEnumerable. 因此,没有什么告诉我们每次迭代都必须是稳定的。

我可以想象以下用例:

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

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

所以——如果你还想考虑奇怪的边缘情况,答案应该是“<strong>no”。

于 2008-10-03T14:26:54.177 回答
3

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

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

简而言之,除非你知道集合类的内部实现,否则不要假设任何关于顺序的事情。

于 2008-10-03T14:29:15.953 回答
2

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

于 2012-04-27T13:31:00.853 回答
1

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

SortedList<,> 之类的东西显然有自己的规则。

于 2008-10-03T14:31:45.587 回答
0

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

于 2008-10-03T14:24:34.557 回答