This is a migrated thread and some comments may be shown as answers.

Iteration variable is used in a labda expression

1 Answer 42 Views
Code Analysis
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
Stuart Hemming
Top achievements
Rank 2
Stuart Hemming asked on 12 Nov 2012, 03:39 PM
Why is this considered something that should be considered worth warning people about?

I ask, purely in the spirit of furthering my own eduction.

--
Stuart

1 Answer, 1 is accepted

Sort by
0
Zdravko
Telerik team
answered on 13 Nov 2012, 10:00 AM
Hello,

 Thanks for contacting us.

For an example I will give you the following code:

var values = new List<int>() { 100, 110, 120 };
var funcs = new List<Func<int>>();
foreach(var v in values) 
  funcs.Add( ()=>v );
foreach(var f in funcs) 
  Console.WriteLine(f());

In versions older than C# 5 this code will return values 120/ 120/ 120.
Because ()=>v means "return the current value of variable v", not "return the value v was back when the delegate was created". Closures close over variables, not over values. And when the methods run, clearly the last value that was assigned to v was 120, so it still has that value.
This is how the loop body is implemented in the versions before C# 5:
{
    IEnumerator<int> e = ((IEnumerable<int>)values).GetEnumerator();
    try
    { 
      int m; // OUTSIDE THE ACTUAL LOOP
      while(e.MoveNext())
      {
        m = (int)(int)e.Current;
        funcs.Add(()=>m);
      }
    }

and in version C# 5 the variable is moved inside the loop body so a fresh variable is created:
try
    { 
      while(e.MoveNext())
      {
        int m; // INSIDE
        m = (int)(int)e.Current;
        funcs.Add(()=>m);
      }

Each closure is closed over a different variable, which is only assigned to once, so it always keeps the correct value.

Thanks.
I hope I was detailed enough.

Greetings,
Zdravko
the Telerik team

Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

Tags
Code Analysis
Asked by
Stuart Hemming
Top achievements
Rank 2
Answers by
Zdravko
Telerik team
Share this question
or