在闭包中捕获变量时,如何添加大括号会更改生成的IL代码?

时间:2015-07-20 15:43:35

标签: c# closures

在阅读this question的答案后,有一件事我不清楚。用户 David Arno 指出,在以下情况下,编译器将为方法X生成更多IL代码,因为需要额外的大括号。

public Func<int> X()
{
    {
        var i = 1;
        {
            i++;
            {
                return () => i;
            }
        }
    }
}

public Func<int> Y()
{
    var i = 1;
    i++;
    return () => i;
}

我看不出这两段代码之间的区别。对我而言,您可以安全地删除X中的所有大括号。哪一对括号负责额外的IL代码?我认为如果X只有一对括号超过Y,那么代码会更清晰(我认为这足以证明这一点)。

1 个答案:

答案 0 :(得分:0)

我编译了代码并使用ILDASM检查了生成的IL。事实证明,在这种情况下,两种方法的生成代码没有区别。

.method public hidebysig instance int32  '<X>b__0'() cil managed
{
  // Code size       11 (0xb)
  .maxstack  1
  .locals init ([0] int32 CS$1$0000)
  IL_0000:  ldarg.0
  IL_0001:  ldfld      int32 ConsoleApplication1.Test/'<>c__DisplayClass2'::i
  IL_0006:  stloc.0
  IL_0007:  br.s       IL_0009
  IL_0009:  ldloc.0
  IL_000a:  ret
} // end of method '<>c__DisplayClass2'::'<X>b__0'


.method public hidebysig instance int32  '<Y>b__4'() cil managed
{
  // Code size       11 (0xb)
  .maxstack  1
  .locals init ([0] int32 CS$1$0000)
  IL_0000:  ldarg.0
  IL_0001:  ldfld      int32 ConsoleApplication1.Test/'<>c__DisplayClass5'::i
  IL_0006:  stloc.0
  IL_0007:  br.s       IL_0009
  IL_0009:  ldloc.0
  IL_000a:  ret
} // end of method '<>c__DisplayClass5'::'<Y>b__4'