隐式捕获闭包,ReSharper警告

D.R*_*.R. 32 c# resharper closures

我通常知道"隐式捕获关闭"意味着什么,但是,今天我遇到了以下情况:

public static void Foo (Bar bar, Action<int> a, Action<int> b, int c)
{
    bar.RegisterHandler(x => a(c)); // Implicitly captured closure: b
    bar.RegisterHandler(x => b(c)); // Implicitly captured closure: a
}
Run Code Online (Sandbox Code Playgroud)

为什么我也暗中捕获其他动作?如果我评论两条线中的任何一条,另一条不会给我警告.有人知道ReSharper警告我的危险吗?

编辑:ReSharper 8.0.1

Ser*_*rvy 35

这里的问题是,当您关闭变量时,幕后发生的事情是编译器创建一个新的未命名类型,为该块中每个变量关闭的每个变量赋予该类型一个实例字段,为每个匿名提供一个方法该代码块中的方法,然后传递该对象的单个实例.

这意味着第一个委托的生命周期使该闭包对象保持活动状态,并且b除了a内部之外,它还具有对该对象的引用,反之亦然.

现在在你的情况下,这不是一个问题,因为一个Action特别是内存密集的东西,所以保持它存活一段时间并不是真正的问题.

从理论上讲,C#团队可以确保在这种特殊情况下可以为同一个块中的每个闭包创建一个新的未命名类型,但是他们选择不这样做,因为它会使常见情况变得更糟.

  • @DR好吧,正如我所说,在这种情况下,您几乎可以不在乎。如果它们是昂贵的对象并且能够更早地清除它们的内存很重要,那么你就不能为此使用闭包。自己创建新的命名类型,使用方法,以及每种类型中每个操作的实例字段,在此方法中创建它们的实例,等等。闭包实际上并没有让你做任何你不能做的事情,它们只是删除样板代码并使其变得更容易。 (2认同)