Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/258.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#foreach循环-订单*稳定性*有保证吗?_C#_Collections_Foreach - Fatal编程技术网

C#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

假设我有一个给定的集合。在不以任何方式更改集合的情况下,我使用foreach循环了它的内容两次。除了宇宙射线什么的,是否绝对保证两个循环中的顺序是一致的

或者,给定一个包含多个元素的
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
实际上是这样工作的,但当前的实现(可能还有未来的实现)确实如此。