可能重复:
Why is it bad to use a iteration variable in a lambda expression
为什么我会得到:“lambda表达式中的迭代变量可能会产生意外结果”?假设我有以下代码:
Dim writeAbleColumns As String() = {"IsSelected", "IsFeeExpense", "IsSubscriptionRedemption"}
With grid
For Each column As DataGridViewColumn In .Columns
column.ReadOnly = Not Array.Exists(writeAbleColumns, Function(arrElement) column.Name = arrElement)
Next
End With
我收到警告:
Warning 1 Using the iteration variable in a lambda expression may have unexpected results. Instead, create a local variable within the loop and assign it the value of the iteration variable.
我不明白为什么将我的代码更改为以下内容会改变:
Dim writeAbleColumns As String() = {"IsSelected", "IsFeeExpense", "IsSubscriptionRedemption"}
With grid
For Each column As DataGridViewColumn In .Columns
Dim c As DataGridViewColumn = column
column.ReadOnly = Not Array.Exists(writeAbleColumns, Function(arrElement) c.Name = arrElement)
Next
End With
除警告消失外,基本上没有任何变化。我只有另一个变量指向我的变量。为什么警告?可能会发生什么意外的事情?
答案 0 :(得分:15)
lambda绑定到变量,而不是变量在lambda变为委托时的值。当循环变量更新时,绑定到该变量的每个lambda 也会看到变量的值,您可能不需要它。每次迭代循环时创建一个新变量会将每个lambda绑定到一个新的,不同的,不变的变量上。
这是C#和VB的一个主要难点。 在C#5和VB 11中,我们正在改变循环闭包语义以缓解此问题。
有关详细信息,请参阅
Is there a reason for C#'s reuse of the variable in a foreach?
以及蒂姆的文章的最后几段:
http://msdn.microsoft.com/en-us/magazine/cc163362.aspx
和我的文章:
http://ericlippert.com/2009/11/12/closing-over-the-loop-variable-considered-harmful-part-one/
答案 1 :(得分:4)
在你的情况下,什么都不会出错。
问题是如果lambda在循环继续后被保存并使用(例如,在事件处理程序中使用)。 Eric Lippert has a very nice explanation on his blog
哦,this question已经在SO上有很长的参考列表。