Предположим, что мы имеем такой код:
public class Observer
{
public event EventHandler X = delegate { };
}
public class Receiver
{
public void Method(object o) {}
}
public class Program
{
public static void DoSomething(object a, object b, Observer observer, Receiver r)
{
var rCopy = r;
EventHandler action1 = (s, e) => rCopy.Method(a);
EventHandler action2 = (s, e) => r.Method(b);
observer.X += action1;
observer.X += action2;
}
public static void Main(string[] args)
{
var observer = new Observer();
var receiver = new Receiver();
DoSomething(new object(), new object(), observer, receiver);
}
}
Здесь action1
и action2
имеют полностью разделенный набор захваченных переменных - rCopy
был создан специально для этого. Тем не менее, компилятор генерирует только один класс для захвата всего (проверенный сгенерированный IL). Я полагаю, что это сделано по соображениям оптимизации, но это позволяет очень трудно выявлять ошибки утечки памяти: если a
и b
записаны в одном классе, GC не может собрать как по крайней мере до тех пор, пока любой из lambdas ссылка.
Есть ли способ убедить компилятор создать два разных класса захвата? Или любая причина, по которой это невозможно сделать?