При использовании лямбда-выражений или анонимных методов в C # мы должны остерегаться доступа к измененному закрытию ловушка.Например:
foreach (var s in strings)
{
query = query.Where(i => i.Prop == s); // access to modified closure
...
}
Из-за измененного закрытия приведенный выше код приведет к тому, что все предложения Where
в запросе будут основаны на конечном значении s
.
* 1009.* Как объяснено
здесь , это происходит потому, что переменная
s
, объявленная в цикле
foreach
выше, переводится в компилятор так:
string s;
while (enumerator.MoveNext())
{
s = enumerator.Current;
...
}
вместо этого:
while (enumerator.MoveNext())
{
string s;
s = enumerator.Current;
...
}
Как указано здесь , нет никаких преимуществ в производительности для объявления переменной вне цикла, и при нормальных обстоятельствах единственная причина, которую я могу придумать для этого, - это если вы планируетеиспользуйте переменную вне области действия цикла:
string s;
while (enumerator.MoveNext())
{
s = enumerator.Current;
...
}
var finalString = s;
Однако переменные, определенные в цикле foreach
, нельзя использовать вне цикла:
foreach(string s in strings)
{
}
var finalString = s; // won't work: you're outside the scope.
Таким образом, компилятор объявляет переменнуютаким образом, что он очень подвержен ошибкам, которые часто трудно найти и отладить, но не дает ощутимых преимуществ.
Есть ли что-то, что вы можете сделать с циклами foreach
таким образом,не могли бы, если бы они были скомпилированы с внутренней переменной, или это просто произвольный выбор, который был сделан до того, как анонимные методы и лямбда-выражения были доступны или распространены, и который с тех пор не пересматривался?