LINQ查询的结果是否总是保证以正确的顺序出现

本文关键字:顺序 结果 查询 结果是 是否 LINQ | 更新日期: 2023-09-27 18:27:20

问题: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); 
  } 

如果有人能在文档中提供订购说明,这将是完美的。

LINQ查询的结果是否总是保证以正确的顺序出现

  • 对于LINQ to Objects:是的
  • 对于并行LINQ:没有
  • 对于LINQ到表达式树(EF、L2S等):不

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

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

如果你认为这个

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 + "  ");
}

还打印出CCD_ 23。因此,此LINQ查询

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

还应打印出CCD_ 25。

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