Cuando se utilizan expresiones lambda o métodos anónimos en C #, debemos ser cautelosos con respecto al acceso a errores de cierre modificados . Por ejemplo:
foreach (var s in strings)
{
query = query.Where(i => i.Prop == s); // access to modified closure
...
}
Debido al cierre modificado, el código anterior hará que todas las Where
cláusulas de la consulta se basen en el valor final de s
.
Como se explica aquí , esto sucede porque la s
variable declarada en el foreach
bucle anterior se traduce así en el compilador:
string s;
while (enumerator.MoveNext())
{
s = enumerator.Current;
...
}
en lugar de esto:
while (enumerator.MoveNext())
{
string s;
s = enumerator.Current;
...
}
Como se señaló aquí , no hay ventajas de rendimiento para declarar una variable fuera del ciclo, y en circunstancias normales, la única razón que puedo pensar para hacerlo es si planea usar la variable fuera del alcance del ciclo:
string s;
while (enumerator.MoveNext())
{
s = enumerator.Current;
...
}
var finalString = s;
Sin embargo, las variables definidas en un foreach
bucle no pueden usarse fuera del bucle:
foreach(string s in strings)
{
}
var finalString = s; // won't work: you're outside the scope.
Por lo tanto, el compilador declara la variable de una manera que lo hace muy propenso a un error que a menudo es difícil de encontrar y depurar, sin producir beneficios perceptibles.
¿Hay algo que puede hacer con los foreach
bucles de esta manera que no podría si se compilaran con una variable de alcance interno, o es solo una elección arbitraria que se hizo antes de que los métodos anónimos y las expresiones lambda estuvieran disponibles o fueran comunes, y que no ¿ha sido revisado desde entonces?
foreach
sino sobre expresiones lamda que resultan en un código similar al mostrado por el OP ...
String s; foreach (s in strings) { ... }
?