Ao usar expressões lambda ou métodos anônimos em C #, precisamos ter cuidado com o acesso à armadilha de fechamento modificada . Por exemplo:
foreach (var s in strings)
{
query = query.Where(i => i.Prop == s); // access to modified closure
...
}
Devido ao fechamento modificado, o código acima fará com que todas as Wherecláusulas da consulta sejam baseadas no valor final des .
Como explicado aqui , isso acontece porque a svariável declarada no foreachloop acima é traduzida assim no compilador:
string s;
while (enumerator.MoveNext())
{
s = enumerator.Current;
...
}
em vez de assim:
while (enumerator.MoveNext())
{
string s;
s = enumerator.Current;
...
}
Conforme indicado aqui , não há vantagens de desempenho em declarar uma variável fora do loop e, em circunstâncias normais, a única razão pela qual posso pensar nisso é se você planeja usar a variável fora do escopo do loop:
string s;
while (enumerator.MoveNext())
{
s = enumerator.Current;
...
}
var finalString = s;
No entanto, variáveis definidas em um foreachloop não podem ser usadas fora do loop:
foreach(string s in strings)
{
}
var finalString = s; // won't work: you're outside the scope.
Portanto, o compilador declara a variável de uma maneira que a torna altamente propensa a um erro que geralmente é difícil de encontrar e depurar, sem produzir benefícios perceptíveis.
Existe algo que você pode fazer com foreachloops dessa maneira que não seria possível se eles fossem compilados com uma variável com escopo interno ou essa é apenas uma escolha arbitrária que foi feita antes que métodos anônimos e expressões lambda estivessem disponíveis ou comuns e que não foi revisado desde então?
foreach, mas sobre expressões Lamda, resultando em código semelhante como mostrado pelo OP ...
String s; foreach (s in strings) { ... }?