Un de mes collègues est venu à moi avec une question à propos de cette méthode qui se traduit dans une boucle infinie. Le code est un peu trop impliqué à poster ici, mais en gros, le problème se résume à ceci:
private IEnumerable<int> GoNuts(IEnumerable<int> items)
{
items = items.Select(item => items.First(i => i == item));
return items;
}
Ce doit (vous ne le pensez) juste être une voie très inefficace pour créer une copie d'une liste. Je l'ai appelé avec:
var foo = GoNuts(new[]{1,2,3,4,5,6});
Le résultat est une boucle infinie. Étrange.
Je pense que le fait de modifier le paramètre est, stylistiquement une mauvaise chose, j'ai donc modifié le code légèrement:
var foo = items.Select(item => items.First(i => i == item));
return foo;
Qui ont travaillé. Qui est, le programme terminé; aucune exception.
Plusieurs expériences ont montré que cela fonctionne aussi:
items = items.Select(item => items.First(i => i == item)).ToList();
return items;
Comme le fait un simple
return items.Select(item => .....);
Curieux.
Il est clair que le problème a à voir avec la reprogrammation des paramètres, mais seulement si l'évaluation est reportée au-delà de cette déclaration. Si j'ajoute l' ToList()
il fonctionne.
J'ai une vague idée de ce qui va mal. Il ressemble à l' Select
est une itération sur sa propre production. C'est un peu étrange en elle-même, parce que en général, une IEnumerable
lèvera si la collection, il est l'itération des changements.
Ce que je ne comprends pas, parce que je ne suis pas intimement familier avec le fonctionnement interne de la façon dont ça fonctionne, c'est pourquoi la ré-affectation du paramètre sont les causes de cette boucle infinie.
Est-il quelqu'un avec plus de connaissances sur le fonctionnement interne qui serait prêt à m'expliquer pourquoi la boucle infinie se produit ici?