Блог переехал. Актуальная версия поста находится по адресу: http://aakinshin.net/ru/blog/dotnet/closures/.
Язык C# даёт нам возможность пользоваться замыканиями — мощным механизмом, который позволяет анонимным методам и лямбдам захватывать свободные переменные в своём лексическом контексте. И в .NET-мире многие программисты очень любят использовать замыкания, но немногие понимают, как они действительно работают. Начнём с простого примера:
public void Run()
{
int e = 1;
Foo(x => x + e);
}
Ничего сложного тут не происходит: мы просто «захватили» локальную переменную e в лямбду, которая передаётся в некоторый метод Foo. Посмотрим, во что компилятор развернёт такую конструкцию*:
public void Run()
{
DisplayClass c = new DisplayClass();
c.e = 1;
Foo(c.Action);
}
private sealed class DisplayClass
{
public int e;
public int Action(int x)
{
return x + e;
}
}