When using lambda expressions or anonymous methods in C#, we have to be wary of the access to modified closure pitfall. (在C#中使用lambda表达式或匿名方法时,我们必须警惕对修改后的闭包陷阱的访问 。) For example: (例如:)
foreach (var s in strings)
{
query = query.Where(i => i.Prop == s); // access to modified closure
...
}
Due to the modified closure, the above code will cause all of the Where
clauses on the query to be based on the final value of s
. (由于修改了闭包,上面的代码将使查询上的所有Where
子句都基于s
的最终值。)
As explained here , this happens because the s
variable declared in foreach
loop above is translated like this in the compiler: (正如解释在这里 ,这是因为在s
中声明的变量foreach
上面的循环被翻译这样的编译:)
string s;
while (enumerator.MoveNext())
{
s = enumerator.Current;
...
}
instead of like this: (而不是像这样:)
while (enumerator.MoveNext())
{
string s;
s = enumerator.Current;
...
}
As pointed out here , there are no performance advantages to declaring a variable outside the loop, and under normal circumstances the only reason I can think of for doing this is if you plan to use the variable outside the scope of the loop: (如此处所指出的, 在循环外声明变量没有任何性能优势,在正常情况下,我可以想到的唯一原因是如果您打算在循环范围外使用变量:)
string s;
while (enumerator.MoveNext())
{
s = enumerator.Current;
...
}
var finalString = s;
However variables defined in a foreach
loop cannot be used outside the loop: (但是,在foreach
循环中定义的变量不能在循环外使用:)
foreach(string s in strings)
{
}
var finalString = s; // won't work: you're outside the scope.
So the compiler declares the variable in a way that makes it highly prone to an error that is often difficult to find and debug, while producing no perceivable benefits. (因此,编译器以某种方式声明该变量,使其极易出现通常难以查找和调试的错误,同时不会产生明显的收益。)
Is there something you can do with foreach
loops this way that you couldn't if they were compiled with an inner-scoped variable, or is this just an arbitrary choice that was made before anonymous methods and lambda expressions were available or common, and which hasn't been revised since then? (是否可以使用foreach
循环以这种方式进行处理,如果它们是使用内部作用域变量编译的,则无法做到,还是只是在匿名方法和lambda表达式可用或通用之前做出的任意选择,以及从那以后没有修改过?)
ask by StriplingWarrior translate from so 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…