Comment parcourir une collection qui prend en charge IEnumerable?

Réponses:

155

Un habitué pour chacun fera:

foreach (var item in collection)
{
    // do your stuff   
}
Fredrik Mörk
la source
C'est plus rapide que .ElementAt (). Malheureusement, mon vote est verrouillé sur la réponse d'Alexa, je ne peux donc pas l'annuler, mais c'est la meilleure réponse. +1
Leo Gurdian
Alors, comment corrigez-vous alors "Énumération multiple possible de IEnumerable"?
SharpC
1
@SharpC: le moyen le plus simple est d'extraire le résultat dans un List <T> ou un tableau, puis de le transmettre aux différents endroits qui doivent le parcourir. Cela garantit que l'énumération (potentiellement coûteuse) du résultat ne se produit qu'une seule fois, mais au prix du stockage du résultat en mémoire. Ma première étape serait de savoir si l'énumération multiple est réellement un problème ou non.
Fredrik Mörk
94

Outre les méthodes déjà suggérées pour l'utilisation d'une foreachboucle, j'ai pensé mentionner également que tout objet implémentant IEnumerablefournit également une IEnumeratorinterface via la GetEnumeratorméthode. Bien que cette méthode ne soit généralement pas nécessaire, elle peut être utilisée pour itérer manuellement sur des collections et est particulièrement utile lors de l'écriture de vos propres méthodes d'extension pour les collections.

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

Un excellent exemple est lorsque vous souhaitez itérer sur deux séquences simultanément , ce qui n'est pas possible avec une foreachboucle.

Noldorin
la source
7
N'oubliez pas de disposer le recenseur.
Eric Lippert
@Eric: Oui, j'ajouterai ça parce que c'est facile à rater.
Noldorin
1
Je pense que cela ne fonctionnera que pour les objets IEnumerable <T> et non pour IEnumerable. J'ai eu un cas générique dans lequel je devais effectuer un cast en IEnumerable et, par conséquent, je n'avais pas la méthode GetEnumerator disponible. Bien pour la plupart des cas en tout cas.
Fabio Milheiro
50

ou même une méthode à l'ancienne très classique

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   
}

peut-être aimeriez-vous aussi cette méthode :-)

Alexa Adrian
la source
9
Pourquoi cela a-t-il autant de votes positifs? Cela énumérera les énumérables 2n fois au lieu d'une fois.
Roman Reiner
1
@RomanReiner parce que cela fonctionne, certaines personnes ne se
soucient
@RomanReiner c'est un bon exemple, je dois attribuer chaque élément d'une collection à une autre collection, je pense que je ne peux pas le faire en utilisant foreach
AminM
1
Si vous regardez l'implémentation de ElementAt, vous découvrirez que si la collection est un IList, ils renvoient l'élément à l'index en utilisant []; donc même performance que [], cependant; sinon, ils obtiendront Enumerator et commenceront une itération séquentiellement à la recherche de l'élément avant de le retourner, donc fondamentalement pour chaque élément, ils créeront un nouvel énumérateur et navigueront à nouveau dans la liste ...
Israel Garcia
1
C'est pire que tout ça, IEnumerable ne prend pas en charge Count () ou ElementAt (). Je pense qu'il pense à un IList. Cela ne répond pas du tout à la question.
krowe
8
foreach (var element in instanceOfAClassThatImplelemntIEnumerable)
{

}
Darin Dimitrov
la source
0

Peut-être avez-vous oublié l' attente avant de retourner votre collection

Elialber Lopes
la source