假设我们有这样的代码:
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 无法收集至少只要 任何 的 lambda 被引用。
有没有办法说服编译器生成两个不同的捕获类?或者有什么原因不能完成?
最佳答案
您重新发现了在 C# 中实现匿名函数的一个已知缺点。 I described the problem in my blog in 2007.
Is there a way to convince compiler to produce two different capture classes?
没有。
Or any reason why it cannot be done?
理论上没有理由可以设计出一种改进的算法来划分封闭变量,以便将它们提升到不同的封闭类中。出于实际原因,我们没有这样做:算法很复杂,正确和测试的成本很高,而且我们一直有更高的优先级。希望 Roslyn 会改变这种情况,但我们不做任何保证。
关于c# - 为什么 C# 编译器生成单个类来捕获多个 lambda 的变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12009309/