I think the order of elements retrieved by a LINQ
is preserved, at least for LINQ to Object
, for LINQ to SQL or Entity
, it may depend on the order of the records in the table. For LINQ to Object
, I'll try explaining why it preserves the order.
In fact when the LINQ
query is executed, the IEnumerable
source will call to GetEnumerator()
to start looping with a while loop
and get the next element using MoveNext()
. This is how a foreach
works on the IEnumerable
source. We all know that a foreach
will preserve the order of the elements in a list/collection. Digging more deeply into the MoveNext()
, I think it just has some Position
to save the current Index
and MoveNext()
just increase the Position
and yield
the corresponding element (at the new position). That's why it should preserve the order, all the code changing the original order is redundant or by explicitly calling to OrderBy
or OrderByDescending
.
If you think this
int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
foreach(var i in numbers)
if(i < 5) Console.Write(i + " ");
prints out 4 1 3 2 0
you should think this
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 + " ");
}
also prints out 4 1 3 2 0
. Hence this LINQ
query
var lowNums = from n in numbers
where n < 5
select n;
foreach (var i in lowNums) {
Console.Write(i + " ");
}
should also print out 4 1 3 2 0
.
Conclusion: The order of elements in LINQ
depends on how MoveNext()
of an IEnumerator
obtained from an IEnumerable
is implemented. However, it's for sure that the order of elements in LINQ
result will be the same order a foreach
loop works on the elements.