#1,183 – How to Correctly Capture a for Loop Variable in a Lambda Expression
September 16, 2014 2 Comments
If you directly capture a for loop variable within a lambda expression, the value used when executing the expression will typically be the value of the variable at the time that the loop exits. If you instead want to capture a variable whose value is the value of the for loop variable while the loop is executing, you can use a local variable.
Action[] dels = new Action[3]; // How to correctly capture for loop variable for (int i = 0; i < 3; i++) { int iLocal = i; dels[i] = () => Console.WriteLine(iLocal + 1); } // Prints 1/2/3 foreach (Action d in dels) d();
Why? What´s the difference between “int i” and int iLocal in this loop?
iLocal is a variable local to the body of the loop. When it is captured by a lambda expression, each delegate instance captures a different variable because of the scope. This results in the (correct) 1/2/3 output. int i is a loop variable and there is only one of them. If you capture i instead of iLocal, you’ll get different results because each delegate instance will use the same copy of i. (See post #1,182).