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

Mat*_*els 76 c# foreach operator-precedence

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

我发现关于同一主题的另一个问题,但我觉得它不能满足我的问题.

有人说未定义任何订单.但正如其他人所说,它遍历数组的顺序是固定的(从0到长度-1).8.8.4 foreach声明

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

List(t).Enumerator没有运气也查看了文档.

另一个相关问题表明,对于Java,它在文档中特别提到:

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

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

提前致谢.

编辑:感谢所有人的所有答案(令人惊讶的是我收到了如此多的回复).我从所有答案中理解的是,List<T>它总是按照索引的顺序迭代.但我仍然希望看到明确的文档和平,说明这一点,类似于Java文档List.

Jon*_*eet 94

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

我不相信它是明确记录的 - 至少,我没有找到这样的文件 - 但我认为你可以把它当作保证.对该顺序的任何更改都会毫无意义地破坏所有类型的代码.事实上,我会惊讶地看到任何实施IList<T>都违背了这一点.不可否认,看到它具体记录下会很高兴......

  • @yazanpro:`foreach`肯定会按照数组顺序迭代. (11认同)

小智 24

在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();
}
Run Code Online (Sandbox Code Playgroud)

希望它仍然与某人相关


Rvd*_*vdK 8

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

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();
  }
}
Run Code Online (Sandbox Code Playgroud)

产生的输出如下: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.
Run Code Online (Sandbox Code Playgroud)

  • 但这是一个实施细节.列表<T>不是*必需*以使用数组作为其后备存储. (9认同)
  • 我想指出List <T>的文档(n代码示例):"List <(Of <(T>)>)类是ArrayList类的通用等价物.它实现了IList <(Of <(T>)>)使用***数组***的通用接口,其大小根据需要动态增加." (强调我的) (3认同)
  • 是的,但这是一个阵列.它是否也自动保留List <T>类? (2认同)
  • List <T>使用数组作为其后备存储.是的 (2认同)