C#foreach循环-订单*稳定性*有保证吗?
假设我有一个给定的集合。在不以任何方式更改集合的情况下,我使用foreach循环了它的内容两次。除了宇宙射线什么的,是否绝对保证两个循环中的顺序是一致的 或者,给定一个包含多个元素的C#foreach循环-订单*稳定性*有保证吗?,c#,collections,foreach,C#,Collections,Foreach,假设我有一个给定的集合。在不以任何方式更改集合的情况下,我使用foreach循环了它的内容两次。除了宇宙射线什么的,是否绝对保证两个循环中的顺序是一致的 或者,给定一个包含多个元素的HashSet,是什么导致以下注释行的输出不相等: { var mySet = new HashSet<string>(); // Some code which populates the HashSet<string> // Output1 printCo
HashSet
,是什么导致以下注释行的输出不相等:
{
var mySet = new HashSet<string>();
// Some code which populates the HashSet<string>
// Output1
printContents(mySet);
// Output2
printContents(mySet);
}
public void printContents(HashSet<string> set) {
foreach(var element in set) {
Console.WriteLine(element);
}
}
{
var mySet=newhashset();
//填充哈希集的一些代码
//输出1
打印内容(mySet);
//输出2
打印内容(mySet);
}
公共无效打印内容(哈希集){
foreach(集合中的var元素){
控制台写入线(元素);
}
}
如果我能得到一个一般性的答案,解释是什么导致实现不符合上述标准,那将是很有帮助的。具体来说,我对
字典
、列表
和数组感兴趣。实现IEnumerable
的一切都是以自己的方式实现的。任何给定的集合都不能保证稳定性
如果您特别提到系列
(),我看不到其MSDN参考中有任何具体保证,即订购是一致的
它可能是一致的吗?对有书面保证吗?我找不到。对于许多C#收藏,都有分类的版本。例如,a对a就像a对a一样。如果您使用的是顺序不重要的东西,如
字典
,那么您不能假设循环顺序每次的行为都是相同的。数组枚举保证顺序
List
和List
预计将提供稳定的顺序(因为它们预计将实现顺序索引元素)
字典、哈希集均显式不保证顺序。两次调用一个接一个地迭代项目不太可能以不同的顺序返回项目,但没有保证或期望。人们不应该期待任何特定的秩序
字典/哈希集的已排序版本按排序顺序返回项
其他IEnumerable对象可以自由执行它们想要的任何操作。通常,实现迭代器的方式要符合用户的期望。也就是说,如果提供了显式顺序,则具有隐式顺序的枚举应该是稳定的-预期是稳定的。对未指定顺序的数据库的查询应以半随机顺序返回项目
检查此问题中的链接:根据您使用
HashSet
的示例,我们现在有了要检查的源代码:
实际上,迭代Slot[]set.m_slots
数组。
数组对象仅在方法trimpress
、Initialize
(这两种方法都仅在构造函数中调用)、OnDeserialization
和SetCapacity
(仅由AddIfNotPresent
和AddOrGetLocation
调用)中更改
m_slot
的值仅在更改HashSet
元素的方法中更改(Clear
,Remove
,AddIfNotPresent
,IntersectWith
,symmetriceExceptwith
)
是的,如果没有任何东西接触到集合,它将以相同的顺序枚举
工作原理完全相同,迭代一个
Entry[]entries
,只有在调用此类非只读方法时才会发生更改。什么样的集合?我最感兴趣的是Dictionary,但最好能对它们进行概述。考虑到.NET的实现只有这么多,我认为,只要看看他们的源代码/反编译,你的运气可能会更好。它不像C++,在那里有一个GalelLIX实现,错误的假设给了你未定义的行为……字典,你肯定不能以相同的顺序枚举。这就是分类词典的作用。好问题。现在请原谅,我创建了一个名为RandomList
的类,枚举器在其中随机迭代元素。姆瓦哈!杰出的更不用说,集合的顺序并不重要,因此根据定义,HashSet仍然正确,因为它不总是以相同的顺序返回内容。SortedSet当然会。@Hexxagonal:哈希集在不保证稳定的迭代顺序方面是正确的。实际上,如果在迭代之间对同一哈希集迭代两次而不更改其内部状态,则可能会得到相同的顺序。第一次迭代不太可能改变内部状态。再说一次,可能是这样。因此无法保证:-)Collection.GetEnumerator()如何不以稳定的顺序返回内容?它定义了这意味着您可以为(var i=0;i,并保证可以看到所有元素。如果不产生稳定的枚举顺序,这是不可能的,对吗?或者,至少,您可以编写自己的枚举器,使用Item(int)
,因为它必须是稳定的才能使用。@binki:实际上,您是对的。不能保证Collection
实际上是这样工作的,但当前的实现(可能还有未来的实现)确实如此。