Dire que j'ai une classe:Liste <T> .foreach par rapport à l'extension personnalisée IEnumerable <T>
public class MyClass
{
...
}
et une méthode de webservice qui retourne un IEnumerable<MyClass>
Le consommateur du webservice définit une méthode:
Maintenant, le consommateur peut appeler leDoSomething
sur le résultat de la méthode de service Web de deux façons:Maintenant, le consommateur peut appeler
DoSomething
sur le résultat de la méthode de service Web de deux manières:
var result = // web service call
foreach(var myClass in result)
{
DoSomething(myClass);
}
ou:
var result = // web service call
result.ToList().ForEach(DoSomething);
Inutile de dire que je préfère de beaucoup la seconde manière, car il est beaucoup plus court et plus expressif (une fois que vous vous habituez à la syntaxe, que j'ai).
Maintenant, la méthode de service Web expose seulement une IEnumerable<MyClass>
, mais il retourne en fait un List<MyClass>
qui (AFAIK) signifie que l'objet sérialisé réelle est encore un List<T>
. Cependant, j'ai trouvé (en utilisant le réflecteur) que la méthode Linq ToList()
fait une copie de tous les objets dans le IEnumerable<T>
quel que soit le type d'exécution réel (à mon avis, il pourrait avoir casté l'argument à un List<T>
s'il était déjà un).
Cela a évidemment un certain surcoût de performance, en particulier pour les grandes listes (ou les listes d'objets volumineux).
Alors, que puis-je faire pour résoudre ce problème, et pourquoi n'y a-t-il pas de méthode ForEach
dans Linq? Par ailleurs, sa question est vaguement liée à this one.
"Pourquoi n'y a-t-il pas de méthode ForEach dans Linq?": Http://stackoverflow.com/questions/800151/why-is- foreach-on-ilistt-and-not-on-ienumerablet –
'ToList()' ne fait pas de copie des objets sauf s'ils sont de type valeur. Au lieu de cela, il crée une liste avec les mêmes références, ce qui permet une modification de la liste d'origine lorsque la boucle est encore active (dans certains cas, vous pouvez le vouloir). Il permet également l'utilisation d'un délégué variable, dans le cas où l'action 'DoSomething' dépend d'autre chose ou est un argument, et c'est probablement le cas où' ForEach' est logique - bien que vous puissiez vous en passer. – RedGlyph