Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do I get: "iteration variable in a lambda expression may have unexpected results" [duplicate]

Tags:

.net

vb.net

Possible Duplicate:
Why is it bad to use a iteration variable in a lambda expression

Why do I get: "iteration variable in a lambda expression may have unexpected results"? Suppose I have the following code:

  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

I get the warning:

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.

I don't understand why changing my code to the following changes anything:

  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

Fundamentally nothing changes except the warning disappears. I just have another variable point to my variable. Why the warning? What unexpected things might happen?

like image 998
Denis Avatar asked Dec 01 '22 00:12

Denis


2 Answers

The lambda is bound to the variable, not to the value the variable had when the lambda was turned into a delegate. As the loop variable updates, every lambda created bound to that variable also sees the changed value of the variable, which you might not want. Creating a new variable every time you iterate the loop binds each lambda over a new, different, unchanging variable.

This is a major pain point in C# and VB. In C# 5 and VB 11 we are changing the loop closure semantics to mitigate this problem.

For more information see

Is there a reason for C#'s reuse of the variable in a foreach?

and the last few paragraphs of Tim's article:

http://msdn.microsoft.com/en-us/magazine/cc163362.aspx

and my article:

http://ericlippert.com/2009/11/12/closing-over-the-loop-variable-considered-harmful-part-one/

like image 197
Eric Lippert Avatar answered Dec 05 '22 00:12

Eric Lippert


In your case, nothing can go wrong.

The issue is if that lambda gets saved and used after the loop continues (for example, used in an event handler). Eric Lippert has a very nice explanation on his blog.

Oh, and this question already has a very long list of references here on SO.

like image 38
Ben Voigt Avatar answered Dec 04 '22 23:12

Ben Voigt