对于每个循环,c#to list 的c#按什么顺序迭代?
-
22-09-2019 - |
题
我想知道C#循环中的一个foreach循环通过A 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
.
解决方案
上 Microsoft参考源页面 为了 List<T>
枚举者明确指出,迭代是从0到长度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();
}
希望它仍然与某人有关
其他提示
基本上取决于 IEnumerator
实施 - 但是 List<T>
它将始终按照列表的自然顺序进行,即与索引器相同的顺序: list[0]
, list[1]
, list[2]
等等
我不认为它已明确记录 - 至少我没有找到这样的文档 - 但我认为您可以保证它。对该订购的任何更改都会毫无意义地打破各种代码。实际上,看到任何实施 IList<T>
这不服从这一点。诚然,很高兴看到它专门记录了...
在您的链接中,公认的答案在 C#语言规范版本3.0,第240页:
foreach遍历数组的元素的顺序如下:对于单维数组元素以增加索引顺序遍历索引顺序,从索引0开始,并以索引长度结束 - 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.
该顺序是由用于使用foreach循环遍历数据集合的迭代器来定义的。
如果您使用的是可索引的标准集合(例如列表),则它将以索引0开头并向上移动。
如果您需要控制订单,则可以控制集合的迭代如何处理 实施自己的iEnumerable, ,或者您可以在执行foreach循环之前按照所需的方式对列表进行排序。
这解释了如何 枚举者 为通用列表工作。首先,当前元素是未定义的,并使用moveNext进入下一个项目。
如果您阅读 movenext 它表明它将从集合的第一个元素开始,然后从那里移动到下一个元素,直到达到集合的末尾为止。
列表似乎以订单返回的项目返回后备用商店 - 因此,如果以这种方式将其添加到列表中,它们将被返回。
如果您的程序取决于订购,则可能需要在浏览列表之前对其进行排序。
线性搜索有些愚蠢 - 但是,如果您需要以某种方式订单,最好的选择是按该顺序制作项目。
我只需要做类似的事情,例如快速攻击代码,尽管它对我试图做的事情无效,但它确实为我重新排序了。
使用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