我想知道C#中的foreach循环遍历System.Collections.Generic.List<T>
对象的顺序。
我发现another question关于同一主题,但我觉得它不能满足我的问题。
有人说未定义任何订单。但正如其他人所说,它遍历数组的顺序是固定的(从0到长度-1)。 8.8.4 The foreach statement
还有人说,对于任何带有订单的标准类(例如List<T>
)都是如此。我找不到任何文件来支持这一点。所以我知道它现在可能会起作用,但也许在下一个.NET版本中它会有所不同(即使它可能不太可能)。
我还没有运气看过List(t).Enumerator
文档。
Another related question指出,对于Java,它在文档中特别提到:
List.iterator()
返回此列表中元素的迭代器 按照正确的顺序。“
我在C#文档中寻找类似的内容。
提前致谢。
编辑:感谢所有人的所有答案(令人惊讶的是我得到了如此多的回复)。我从所有答案中理解的是List<T>
总是按照索引的顺序迭代。但我仍然希望看到明确的文件和平,说明这一点,类似于Java documentation on List
。
答案 0 :(得分:93)
基本上由IEnumerator
实现决定 - 但对于List<T>
,它将始终按照列表的自然顺序进行,即与索引器的顺序相同:list[0]
,{ {1}},list[1]
等。
我不相信它是明确记录的 - 至少,我没有找到这样的文件 - 但我认为你可以把它当作保证。对该顺序的任何更改都会毫无意义地破坏所有类型的代码。事实上,我会惊讶地看到list[2]
的任何实施违反了这一点。不可否认,看到它具体记录下来会很高兴......
答案 1 :(得分:8)
在您的链接中,接受的答案在C# Language Specification Version 3.0, page 240中说明:
foreach遍历的顺序 数组的元素是 如下:对于一维数组 元素越来越多 索引顺序,从索引0开始 以索引长度结束 - 1.对于 多维数组,元素是 遍历了这样的指数 最右边的尺寸增加了 首先,然后是下一个左维, 等等到左边。下列 示例打印出a中的每个值 元素中的二维数组 顺序:
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.
答案 2 :(得分:5)
在List<T>
枚举器的Microsoft Reference Source page中,明确指出迭代是从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();
}
希望它仍然与某人相关
答案 3 :(得分:4)
顺序由迭代器定义,迭代器用于使用foreach循环遍历数据集合。
如果您使用的是可索引的标准集合(例如List),那么它将遍历从索引0开始并向上移动的集合。
如果您需要控制排序,您可以控制implementing your own IEnumerable处理集合的迭代方式,也可以在执行foreach循环之前按照您希望的方式对列表进行排序。
这解释了Enumerator如何适用于通用列表。首先,当前元素未定义,并使用MoveNext到达下一个项目。
如果您阅读MoveNext,则表示它将从集合的第一个元素开始,然后从那里移动到下一个元素,直到它到达集合的末尾。
答案 4 :(得分:1)
列表似乎按照它们在后备存储中的顺序返回项目 - 所以如果它们以这种方式添加到列表中,它们将以这种方式返回。
如果您的程序取决于订购,您可能希望在遍历列表之前对其进行排序。
线性搜索有些愚蠢 - 但如果您需要某种方式订购,那么最好的选择就是按顺序制作商品。
答案 5 :(得分:1)
我只需要做一些类似于快速破解代码的事情,虽然它不能用于我试图做的事情但它为我重新排序列表。
使用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