每个循环的 C# 以什么顺序迭代 List<T>?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1790245/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 20:51:15  来源:igfitidea点击:

In what order does a C# for each loop iterate over a List<T>?

c#foreachoperator-precedence

提问by Matthijs Wessels

I was wondering about the order that a foreach loop in C# loops through a System.Collections.Generic.List<T>object.

我想知道 C# 中的 foreach 循环遍历System.Collections.Generic.List<T>对象的顺序。

I found another questionabout the same topic, but I do not feel that it answers my question to my satisfaction.

我发现关于同一主题的另一个问题,但我觉得它不能让我满意地回答我的问题。

Someone states that no order is defined. But as someone else states, the order it traverses an array is fixed (from 0 to Length-1). 8.8.4 The foreach statement

有人说没有定义顺序。但正如其他人所说,它遍历数组的顺序是固定的(从 0 到 Length-1)。8.8.4 foreach 语句

It was also said that the same holds for any standard classes with an order (e.g. List<T>). I can not find any documentation to back that up. So for all I know it might work like that now, but maybe in the next .NET version it will be different (even though it might be unlikely).

也有人说这同样适用于任何具有订单的标准类(例如List<T>)。我找不到任何文件来支持它。所以就我所知,它现在可能会这样工作,但也许在下一个 .NET 版本中它会有所不同(即使它可能不太可能)。

I have also looked at the List(t).Enumeratordocumentation without luck.

我也List(t).Enumerator没有运气看过文档。

Another related questionstates that for Java, it is specifically mentioned in the documentation:

另一个相关问题指出,对于Java,文档中特别提到:

List.iterator()returns an iterator over the elements in this list in proper sequence."

List.iterator()以适当的顺序返回此列表中元素的迭代器。”

I am looking for something like that in the C# documentation.

我正在 C# 文档中寻找类似的东西。

Thanks in advance.

提前致谢。

Edit: Thank you for all you for all your answers (amazing how fast I got so many replies). What I understand from all the answers is that List<T>does always iterate in the order of its indexing. But I still would like to see a clear peace of documentation stating this, similar to the Java documentation on List.

编辑:感谢你们所有的回答(我收到这么多回复的速度太快了)。我从所有答案中了解到的是,List<T>它总是按照索引的顺序进行迭代。但我还是想看到文档的说明这一点,类似一个明确的和平在Java文档List

采纳答案by apokrovskyi

On Microsoft Reference Source pagefor List<T>Enumerator it is explicitly stated that the iteration is done from 0 to Length-1:

在Enumerator 的Microsoft Reference Source 页面上List<T>明确指出迭代是从 0 到 Length-1 完成的:

internal Enumerator(List<T> list) {
    this.list = list;
    index = 0;
    version = list._version;
    current = default(T);
}

public bool MoveNext() {

    List<T> localList = list;

    if (version == localList._version && ((uint)index < (uint)localList._size)) 
    {                                                     
        current = localList._items[index];                    
        index++;
        return true;
    }
    return MoveNextRare();
}

Hope it's still relevant for somebody

希望它仍然与某人相关

回答by Jon Skeet

Basically it's up to the IEnumeratorimplementation - but for a List<T>it will always go in the natural order of the list, i.e. the same order as the indexer: list[0], list[1], list[2]etc.

基本上它是到IEnumerator执行-但对于List<T>它会在列表中的自然顺序,即相同的顺序与索引总是:list[0]list[1]list[2]等。

I don't believe it's explicitly documented - at least, I haven't found such documentation - but I think you can treat it as guaranteed. Any change to that ordering would pointlessly break all kinds of code. In fact, I'd be surprised to see any implementation of IList<T>which disobeyed this. Admittedly it would be nice to see it specifically documented...

我不相信它有明确的记录——至少,我还没有找到这样的文档——但我认为你可以把它当作保证。对该顺序的任何更改都会毫无意义地破坏各种代码。事实上,我会惊讶地看到任何IList<T>不遵守这一点的实现。诚然,很高兴看到它被特别记录......

回答by Broam

Lists seem to return the items in an order they are in the backing store--so if they are added to the list that way they'll be returned that way.

列表似乎按照它们在后备存储中的顺序返回项目——所以如果它们以这种方式添加到列表中,它们将按这种方式返回。

If your program depends on the ordering, you may want to sort it before traversing the list.

如果您的程序取决于排序,您可能希望在遍历列表之前对其进行排序。

It's somewhat silly for linear searches--but if you need the order a certain way your best bet is make the items in that order.

对于线性搜索来说,这有点愚蠢——但是如果您需要以某种方式排序,那么最好的办法就是按该顺序制作项目。

回答by Brendan Enrick

The order is defined by the iterator being used to traverse a collection of data using a foreach loop.

顺序由用于使用 foreach 循环遍历数据集合的迭代器定义。

If you are using a standard collection that is indexable (such as a List), then it will traverse the collection starting with index 0 and moving up.

如果您使用的是可索引的标准集合(例如 List),那么它将遍历从索引 0 开始并向上移动的集合。

If you need to control the ordering you can either control how the iteration of the collection is handled by implementing your own IEnumerable, or you can sort the list the way you want it before executing the foreach loop.

如果您需要控制排序,您可以通过实现您自己的 IEnumerable来控制如何处理集合的迭代,或者您可以在执行 foreach 循环之前按照您想要的方式对列表进行排序。

This explains how Enumeratorworks for generic List. At first the current element is undefined and uses MoveNext to get to the next item.

这解释了Enumerator如何用于泛型列表。起初,当前元素是未定义的,并使用 MoveNext 到达下一个项目。

If you read MoveNextit indicates that it will start with the first element of the collection and from there move to the next one until it reaches the end of the collection.

如果您阅读MoveNext,它表示它将从集合的第一个元素开始,然后从那里移动到下一个元素,直到到达集合的末尾。

回答by RvdK

In your link, the accepted answer states in C# Language Specification Version 3.0, page 240:

在您的链接中,接受的答案在C# 语言规范版本 3.0,第 240 页中指出:

The order in which foreach traverses the elements of an array, is as follows: For single-dimensional arrays elements are traversed in increasing index order, starting with index 0 and ending with index Length – 1. For multi-dimensional arrays, elements are traversed such that the indices of the rightmost dimension are increased first, then the next left dimension, and so on to the left. The following example prints out each value in a two-dimensional array, in element order:

using System;
class Test
{
  static void Main() {
      double[,] values = {
          {1.2, 2.3, 3.4, 4.5},
          {5.6, 6.7, 7.8, 8.9}
      };
      foreach (double elementValue in values)
          Console.Write("{0} ", elementValue);
      Console.WriteLine();
  }
}

The output produced is as follows: 1.2 2.3 3.4 4.5 5.6 6.7 7.8 8.9 In the example

int[] numbers = { 1, 3, 5, 7, 9 };
foreach (var n in numbers) Console.WriteLine(n);
the type of n is inferred to be int, the element type of numbers.

foreach 遍历数组元素的顺序如下: 对于一维数组,元素以递增的索引顺序遍历,从索引 0 开始,以索引 Length – 1 结束。对于多维数组,元素被遍历这样最右边维度的索引首先增加,然后是下一个左边维度,依此类推到左边。以下示例按元素顺序打印出二维数组中的每个值:

using System;
class Test
{
  static void Main() {
      double[,] values = {
          {1.2, 2.3, 3.4, 4.5},
          {5.6, 6.7, 7.8, 8.9}
      };
      foreach (double elementValue in values)
          Console.Write("{0} ", elementValue);
      Console.WriteLine();
  }
}

产生的输出如下: 1.2 2.3 3.4 4.5 5.6 6.7 7.8 8.9 在例子中

int[] numbers = { 1, 3, 5, 7, 9 };
foreach (var n in numbers) Console.WriteLine(n);
the type of n is inferred to be int, the element type of numbers.

回答by KillJoy

I've just had to do something similar as a quick hack of code, though it didn't work for what I was trying to do it did reorder the list for me.

我只需要做一些类似于快速破解代码的事情,尽管它对我尝试做的事情不起作用,但它确实为我重新排序了列表。

Using LINQ to change the order

使用 LINQ 更改顺序

         DataGridViewColumn[] gridColumns = new DataGridViewColumn[dataGridView1.Columns.Count];
         dataGridView1.Columns.CopyTo(gridColumns, 0); //This created a list of columns

         gridColumns = (from n in gridColumns
                        orderby n.DisplayIndex descending
                        select n).ToArray(); //This then changed the order based on the displayindex