Come scorrere una raccolta che supporta IEnumerable?


Risposte:


155

Un regolare per ciascuno farà:

foreach (var item in collection)
{
    // do your stuff   
}

È più veloce di .ElementAt (). Sfortunatamente, il mio voto è bloccato sulla risposta di Alexa, quindi non posso annullarlo, ma questa è la risposta migliore. +1
Leo Gurdian

Allora come si corregge la "Possibile enumerazione multipla di IEnumerable"?
SharpC

1
@SharpC: il modo più semplice è estrarre il risultato in un List <T> o in un array, quindi passarlo ai vari punti che devono iterare su di esso. Ciò garantisce che l'enumerazione (potenzialmente costosa) del risultato avvenga solo una volta, ma a costo di archiviare il risultato in memoria. Il mio primo passo sarebbe scoprire se l'enumerazione multipla è effettivamente un problema o meno.
Fredrik Mörk

94

Insieme ai metodi già suggeriti per l'utilizzo di un foreachciclo, ho pensato di menzionare anche che qualsiasi oggetto che implementa IEnumerablefornisce anche IEnumeratorun'interfaccia tramite il GetEnumeratormetodo. Sebbene questo metodo di solito non sia necessario, può essere utilizzato per l'iterazione manuale sulle raccolte ed è particolarmente utile quando si scrivono i propri metodi di estensione per le raccolte.

IEnumerable<T> mySequence;
using (var sequenceEnum = mySequence.GetEnumerator())
{
    while (sequenceEnum.MoveNext())
    {
        // Do something with sequenceEnum.Current.
    }
}

Un ottimo esempio è quando si desidera iterare su due sequenze contemporaneamente , cosa che non è possibile con un foreachciclo.


7
Non dimenticare di eliminare l'enumeratore.
Eric Lippert

@ Eric: Sì, lo aggiungerò perché è facile non vederlo.
Noldorin

1
Penso che funzionerà solo per gli oggetti IEnumerable <T> e non per IEnumerable. Avevo un caso generico in cui dovevo eseguire il cast su IEnumerable e, quindi, non avevo il metodo GetEnumerator disponibile. Bello per la maggior parte dei casi comunque.
Fabio Milheiro

50

o anche un metodo vecchio stile molto classico

IEnumerable<string> collection = new List<string>() { "a", "b", "c" };

for(int i = 0; i < collection.Count(); i++) 
{
    string str1 = collection.ElementAt(i);
    // do your stuff   
}

forse ti piacerebbe anche questo metodo :-)


9
Perché questo ha così tanti voti positivi? Questo enumererà l'enumerabile 2n volte invece di una volta.
Roman Reiner

1
@RomanReiner perché funziona, alcune persone non si preoccupano della performance :)
Khateeb321

@RomanReiner questo è un buon esempio, devo assegnare ogni elemento di una raccolta a un'altra raccolta, penso di non poterlo fare usando foreach
AminM

1
Se guardi l'implementazione di ElementAt scoprirai che se la collezione è un IList restituiscono l'elemento all'indice usando []; quindi la stessa prestazione di [], tuttavia; in caso contrario, otterranno Enumerator e inizieranno un'iterazione alla ricerca dell'elemento in sequenza prima di restituirlo, quindi fondamentalmente per ogni elemento creano un nuovo enumeratore e navigano di nuovo nell'elenco ...
Israel Garcia

1
È peggio di tutto ciò, IEnumerable non supporta Count () o ElementAt (). Penso che stia pensando a un ILista. Questo in realtà non risponde affatto alla domanda.
krowe


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.