Quando si usano espressioni lambda o metodi anonimi in C #, dobbiamo stare attenti all'accesso alla trappola della chiusura modificata . Per esempio:
foreach (var s in strings)
{
query = query.Where(i => i.Prop == s); // access to modified closure
...
}
A causa della chiusura modificata, il codice sopra riportato farà sì che tutte le Where
clausole sulla query siano basate sul valore finale di s
.
Come spiegato qui , questo accade perché la s
variabile dichiarata nel foreach
ciclo sopra è tradotta in questo modo nel compilatore:
string s;
while (enumerator.MoveNext())
{
s = enumerator.Current;
...
}
invece di così:
while (enumerator.MoveNext())
{
string s;
s = enumerator.Current;
...
}
Come sottolineato qui , non ci sono vantaggi prestazionali nel dichiarare una variabile al di fuori del ciclo, e in circostanze normali l'unica ragione a cui posso pensare per farlo è se pensi di usare la variabile al di fuori dell'ambito del ciclo:
string s;
while (enumerator.MoveNext())
{
s = enumerator.Current;
...
}
var finalString = s;
Tuttavia, le variabili definite in un foreach
loop non possono essere utilizzate al di fuori del loop:
foreach(string s in strings)
{
}
var finalString = s; // won't work: you're outside the scope.
Quindi il compilatore dichiara la variabile in un modo che la rende altamente soggetta a un errore che è spesso difficile da trovare e eseguire il debug, senza produrre benefici percepibili.
C'è qualcosa che puoi fare con i foreach
loop in questo modo che non potresti se fossero compilati con una variabile con ambito interno, o è solo una scelta arbitraria che è stata fatta prima che i metodi anonimi e le espressioni lambda fossero disponibili o comuni, e che non ha da allora è stato rivisto?
foreach
ma di espressioni lamda che danno come risultato un codice simile a quello mostrato dall'OP ...
String s; foreach (s in strings) { ... }
?