2013-08-12 6 views
5

Domanda: Il risultato di una query LINQ sarà sempre garantito nell'ordine corretto?Il risultato di una query LINQ sarà sempre garantito nell'ordine corretto?

Esempio:

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

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

Ora, quando camminiamo attraverso le voci del risultato della query, sarà nello stesso ordine in cui i dati di ingresso numbers è ordinato?

Se qualcuno può fornire una nota sull'ordinazione nella documentazione, questo sarebbe perfetto.

+0

Utilizzare 'var lowNums = numbers.Where (x => x <5).OrderBy (x => x); ' –

+1

Forse questo aiuta: http://stackoverflow.com/questions/6146724/do-linqs-enumerable-methods-maintain-relative-order-of-elements. Se è un oggetto IEnumerable, manterrà l'ordine originale. – thepirat000

risposta

4
+0

Trovate documentazione che garantisca che l'ordine sia lo stesso per Linq-To-Objects? –

+0

@TimSchmelter Sono abbastanza sicuro che i doc dicono il contrario, o meglio, non dicono nulla. – evanmcdonnal

+0

@evanmcdonnal: Sono abbastanza sicuro che i documenti non dicono nulla anche se sono sicuro che non cambi l'ordine in "Select" o altri metodi linq. –

0

ritengo l'ordine degli elementi recuperati da un LINQ è conservato, almeno per LINQ to Object, per LINQ to SQL or Entity, può dipendere dall'ordine dei record della tabella. Per LINQ to Object, proverò a spiegare perché conserva l'ordine.

Infatti quando viene eseguita la query LINQ, la fonte IEnumerable chiamerà per GetEnumerator() per iniziare il ciclo con un while loop e ottenere l'elemento successivo utilizzando MoveNext(). Questo è il modo in cui un foreach funziona sulla sorgente IEnumerable. Sappiamo tutti che un foreach manterrà l'ordine degli elementi in un elenco/raccolta. Scavando più a fondo nel MoveNext(), penso che abbia solo qualche Position per salvare l'attuale Index e MoveNext() semplicemente aumentare il Position e yield l'elemento corrispondente (nella nuova posizione). Ecco perché è necessario conservare l'ordine, , tutto il codice che modifica l'ordine originale è ridondante o chiamando esplicitamente a OrderBy o OrderByDescending.

Se pensi che questo

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

stampe fuori 4 1 3 2 0 si dovrebbe pensare che questo

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

stampa anche fuori 4 1 3 2 0. Quindi questo LINQ interrogazione

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

dovrebbe anche stampare 4 1 3 2 0.

Conclusione: L'ordine degli elementi in LINQ dipende da come MoveNext() di un IEnumerator ottenuto da un IEnumerable è implementato. Tuttavia, è certo che l'ordine degli elementi nel risultato LINQ sarà lo stesso ordine in cui un ciclo foreach funziona sugli elementi.