そのようなコードがあると仮定します:
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
これのために特別に作成されました。それでも、コンパイラはすべてをキャプチャするために1つのクラスのみを生成します(生成されたILをチェック)。最適化の理由で行われていると思いますが、メモリリークのバグを見つけるのが非常に困難です。単一のクラスでキャプチャされた場合a
、少なくともラムダのいずれかが参照b
されている限り、GCは両方を収集できません。
コンパイラに2つの異なるキャプチャクラスを生成するように説得する方法はありますか?またはそれができない理由は何ですか?