HashSet 是否保留枚举之间的顺序?

Does HashSet preserve order between enumerations?

This Whosebug 答案完全描述了 HashSet 是无序的,其项目枚举顺序未定义,不应依赖。

然而,

这又引出了另一个问题:我应该还是不应该依赖两个或多个后续枚举之间的枚举顺序?鉴于没有插入或删除。

例如,假设我已将一些项目添加到 HashSet:

HashSet<int> set = new HashSet<int>();
set.Add(1);
set.Add(2);
set.Add(3);
set.Add(4);
set.Add(5);

现在,当我通过 foreach 枚举这个集合时,假设我收到这个序列:

// Result: 1, 3, 4, 5, 2.

问题是:如果我不做任何修改,我一次又一次地枚举设置,顺序会保留吗? 会一直一样吗

实际上,枚举之间可能总是相同的,但是 IEnumerable 的描述中没有提供该假设,并且实现者可以决定 return 然后以它想要的任何顺序。

谁知道它在幕后做了什么,将来是否会继续以同样的方式做。例如,HashSet 的未来实现可能会被优化以检测低内存条件并重新排列其内存中的内容,从而影响它们 returned 的顺序。所以 99.9% 的时间他们会以相同的顺序返回,但是如果你开始耗尽内存资源,它会突然 return 以不同的顺序返回。

底线是我不会依赖枚举顺序随着时间的推移保持一致。如果顺序对你很重要,那么在 set.OrderBy(x => x) 上执行你的 foreach,这样你就可以确保它是你想要的顺序。