web-dev-qa-db-fra.com

Exemple de code du revendeur pour expliquer "Énumération multiple possible de IEnumerable"

Parfois, Resharper met en garde sur:

Énumération multiple possible de IEnumerable

Il y a ne question SO sur la façon de traiter ce problème , et le site ReSharper explique également les choses ici . Il contient un exemple de code qui indique vous faire cela à la place:

IEnumerable<string> names = GetNames().ToList();

Ma question concerne cette suggestion spécifique: cela n'entraînera-t-il toujours pas une énumération deux fois dans la collection dans les 2 boucles pour chaque?

63
user2250250

GetNames() renvoie un IEnumerable. Donc, si vous stockez ce résultat:

IEnumerable foo = GetNames();

Ensuite, chaque fois que vous énumérez foo, la méthode GetNames() est appelée à nouveau (pas littéralement, je ne trouve pas de lien expliquant correctement les détails, mais reportez-vous à IEnumerable.GetEnumerator() ).

Resharper voit cela et vous suggère de stocker le résultat de l'énumération GetNames() dans une variable locale, par exemple en le matérialisant dans une liste:

IEnumerable fooEnumerated = GetNames().ToList();

Cela fera en sorte que le résultat GetNames() ne soit énuméré qu'une fois, tant que vous vous référez à fooEnumerated.

Cela importe parce que vous souhaitez en général énumérer une seule fois, par exemple lorsque GetNames() effectue un appel (lent) à la base de données.

Parce que vous avez matérialisé les résultats dans une liste, peu importe que vous énumériez fooEnumerated deux fois; vous allez parcourir deux fois une liste en mémoire.

158
CodeCaster

J'ai trouvé que cette méthode était la meilleure et la plus simple pour comprendre plusieurs énumérations.

C # LINQ: Énumération multiple possible de IEnumerable

https://helloacm.com/c-linq-possible-multiple-enumeration-of-ienumerable-resharper/

9
Ryan

GetNames() n'est pas appelé deux fois. L'implémentation de IEnumerable.GetEnumerator() est appelée à chaque fois que vous souhaitez énumérer la collection avec foreach. Si, dans la IEnumerable.GetEnumerator(), des calculs coûteux sont effectués, cela peut être une raison à prendre en compte.

8
IronMan702

Oui, vous allez l'énumérer deux fois sans aucun doute. mais le fait est que si GetNames() renvoie une requête linq paresseuse dont le calcul coûte très cher, elle sera alors calculée deux fois sans appel à ToList() ou ToArray().

4
Sriram Sakthivel