Lors de l'utilisation des expressions lambda, d'anonymes ou de méthodes en C#, il faut se méfier de l' accès à l'modifié fermeture piège. Par exemple:
foreach (var s in strings)
{
query = query.Where(i => i.Prop == s); // access to modified closure
...
}
En raison de la modification de la fermeture, le code ci-dessus affichera tous les de la Where
des clauses sur la requête soit basée sur la valeur finale de l' s
.
Comme expliqué ici, c'est parce que l' s
variable déclarée en foreach
boucle ci-dessus est traduit comme ceci dans le compilateur:
string s;
while (enumerator.MoveNext())
{
s = enumerator.Current;
...
}
au lieu de cela:
while (enumerator.MoveNext())
{
string s;
s = enumerator.Current;
...
}
Comme l'a souligné ici, il n'y a pas les avantages de performance à la déclaration d'une variable en dehors de la boucle, et dans des circonstances normales, la seule raison pour laquelle je peux penser pour ce faire est si vous prévoyez d'utiliser la variable en dehors de la portée de la boucle:
string s;
while (enumerator.MoveNext())
{
s = enumerator.Current;
...
}
var finalString = s;
Cependant, les variables définies dans un foreach
boucle ne peut pas être utilisé en dehors de la boucle:
foreach(string s in strings)
{
}
var finalString = s; // won't work: you're outside the scope.
Ainsi, le compilateur déclare la variable dans une manière qui le rend très sujettes à une erreur qui est souvent difficile de trouver et de débogage, tout en ne produisant aucun perceptible avantages.
Est-il quelque chose que vous pouvez faire avec foreach
boucles de cette façon qu'on ne pouvait pas s'ils sont compilés avec un intérieur d'étendue variable, ou est-ce juste un choix arbitraire qui a été fait avant les méthodes anonymes et les expressions lambda étaient disponibles ou de la commune, et qui n'a pas été révisée depuis lors?