【问题标题】:Is the .NET foreach statement guaranteed to iterate a collection in the same order in which it was built?.NET foreach 语句是否保证以与构建相同的顺序迭代集合?
【发布时间】:2009-03-04 21:22:48
【问题描述】:

一位同事使用 for 循环在他编写的一些 C# 代码中迭代 List 并留下评论,“没有使用 For Each,因为我不确定它是否按顺序迭代。谁知道 Microsoft 会做什么。”例如,假设我们有一个这样构建的 List:

var someList = new List<string>();

someList.Add("one");
someList.Add("two");
someList.Add("three");

我的同事使用了这样的东西:

for (int i = 0; i < someList.Count; i++)    
{
    System.Diagnostics.Debug.WriteLine(someList[i]);
}

而不是这个:

foreach (var item in someList)              
{
    System.Diagnostics.Debug.WriteLine(item);
}

我猜他担心这些物品的出现顺序可能与它们添加到收藏中的顺序不同。我认为他有点偏执,但从技术上讲,文档没有说明迭代集合的顺序。 foreach 语句是否可以按任何顺序遍历数组或集合对象,而不是从最低到最高?

【问题讨论】:

    标签: .net collections foreach


    【解决方案1】:

    您的问题是关于List&lt;T&gt;,它确实维持秩序。

    单独的 foreach 不能保证做任何事情。它只是询问为其枚举器提供的对象,这可能会做任何事情。

    【讨论】:

    【解决方案2】:

    这取决于集合:

    • 对于List&lt;T&gt;,它保证是插入顺序。 (假设只是Add 调用,如图所示。如果您将元素插入到列表中的特定位置,它们会在您期望的正确位置返回。)基本上它与您通过使用@ 得到的顺序相同987654323@、list[1]list[2]
    • Dictionary&lt;TKey, TValue&gt; 不保证订购。
    • 对于SortedList&lt;TKey, TValue&gt;(等),它将按关键比较顺序排列 - 这就是类型的重点。
    • 数组总是按元素顺序出现。

    【讨论】:

    • 虽然你是对的,但我仍然认为 foreach 仅用于遍历集合中的所有对象,并且绝不保证任何顺序。由集合实现决定 foreach 将选择的顺序。所以使用 foreach 并不能保证行为。
    • @devinb 我认为这就是@Jon 所说的。
    • 好吧,foreach 保证使用集合中的 GetEnumerator - 因此,如果您知道集合的迭代器的顺序,则可以保证您与 foreach 的顺序相同。例如,依靠它按顺序迭代 List 是完全合理的。
    • @Rex 我想我不清楚。我想说的是 foreach 的顺序应该被视为副作用。而 for 循环有保证的顺序。 Jon 掩盖了这一事实并暗示应该使用 foreach。我觉得如果索引顺序是必不可少的,那么 for 循环更安全。
    • @both:哈...好吧,现在我看起来很愚蠢。不过,我会把我的 cmets 留在这里以供后代使用,这样你们看起来就不会什么都不回应了。
    【解决方案3】:

    为了具体回答这个问题,“foreach”返回 .GetEnumerator() 返回的顺序。对于列表,这是您将内容添加到末尾的顺序。对于字典,它可能是分配事物的存储桶的顺序。

    【讨论】:

      猜你喜欢
      • 2012-03-15
      • 2011-06-11
      • 2019-03-17
      • 2019-05-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-14
      相关资源
      最近更新 更多