Back in 2005, with the release of C# 2.0 standard we got a possibility to pass a variable to the body of an anonymous delegate by capturing it from the current context. In 2008 the C# 3.0 brought us lambdas, user anonymous classes, LINQ requests and much more. Now it January, 2017 and the majority of C# developers are looking forward to the release of the C# 7.0 standard that should provide us a bunch of new useful features. However, there are still old features that need to be fixed. That's why there are plenty of ways to shoot yourself in the foot. Today we are going to speak about one of them, and it is related with quite an unobvious mechanism of variable capture in the body of anonymous functions in C#.

Let's take a small example code:

Code:
void Foo()
{
  var actions = new List<Action>();
  for (int i = 0; i < 10; i++)
  {
    actions.Add(() => Console.WriteLine(i));
  }

  foreach(var a in actions)
  {
    a();
  }
}
And now attention please, here is the answer. The console will print the number 10 ten times.

Code:
10
10
10
10
10
10
10
10
10
10
This article is for those who thought otherwise. Let's try to sort out, what are the reasons of such behavior.

Why does it happen so?

Upon the declaration of an anonymous function (it can be an anonymous delegate or lambda) inside your class, one more container class will be declared during the compilation, which contains fields for all the captured variables and a method, containing a body of the anonymous function. The disassembled structure of the program for the code fragment given above will be as follows:

Name:  image2.png
Views: 149
Size:  7.5 KB

In this case the Foo method in this fragment is declared inside the Program class. The compiler generated a container class c__DisplayClass1_0 for the lambda () => Console.WriteLine(i), and inside of the class-container it generated a field i, having a captured variable with the same name and the method b__0, containing the body of the lambda.

Other examples read the article.