7

问题: LINQ 查询的结果是否总是保证顺序正确?

例子:

int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; 

var lowNums = 
  from n in numbers 
  where n < 5 
  select n; 

现在,当我们遍历查询结果的条目时,它是否与输入数据numbers的排序顺序相同?

foreach (var x in lowNums) 
  { 
    Console.WriteLine(x); 
  } 

如果有人可以在文档中提供有关订购的说明,那将是完美的。

4

2 回答 2

6
于 2013-08-12T22:15:43.010 回答
0

我认为 a 检索到的元素的顺序LINQ是保留的,至少 for LINQ to Object, for LINQ to SQL or Entity,它可能取决于表中记录的顺序。对于LINQ to Object,我将尝试解释为什么它会保留顺序。

事实上,当LINQ查询被执行时,IEnumerable源代码会调用 toGetEnumerator()来开始循环 awhile loop并使用 . 获取下一个元素MoveNext()。这就是 aforeachIEnumerable源代码上的工作方式。我们都知道 aforeach将保留列表/集合中元素的顺序。更深入地挖掘MoveNext(),我认为它只是有一些Position保存当前IndexMoveNext()增加Positionyield相应的元素(在新位置)。这就是为什么它应该保留顺序,所有更改原始顺序的代码都是多余的,或者通过显式调用OrderByorOrderByDescending

如果你认为这

int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; 
foreach(var i in numbers)
  if(i < 5) Console.Write(i + "  ");

打印出来4 1 3 2 0你应该这样认为

int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; 
IEnumerator ie = numbers.GetEnumerator();
while(ie.MoveNext()){
  if((int)ie.Current < 5) Console.Write(ie.Current + "  ");
}

也打印出来4 1 3 2 0。因此这个LINQ查询

var lowNums = from n in numbers 
              where n < 5 
              select n;
foreach (var i in lowNums) { 
   Console.Write(i + "  "); 
}

也应该打印出来4 1 3 2 0

结论:元素的顺序LINQ取决于从MoveNext()anIEnumerator获得的 anIEnumerable的实现方式。但是,可以肯定的是,结果中元素的顺序LINQ将与foreach循环在元素上工作的顺序相同。

于 2013-08-13T03:18:52.913 回答