## Sunday, May 17, 2009

### Variable capture in C# closures

You have to be careful about variable capture when constructing lambdas in C#.  The following code does not do what you might imagine:
var xs = new List<Action>();for(var x = 0; x < 10; x++) {   xs.Add(() => {Console.Write(x + " ");});};foreach (var a in xs) {   a();}

This prints the following: 10 10 10 10 10 10 10 10 10 10
The reason is that the variable x is captured by the lambdas, not the value of x at the time the lambda is created.

To avoid this situation we have to make a local copy of x for each lambda:
var xs = new List<Action>();for(var x = 0; x < 10; x++) {   var x_copy = x;   xs.Add(() => {Console.Write(x_copy + " ");});};foreach (var a in xs) {   a();}

This prints 0 1 2 3 4 5 6 7 8 9 as expected.