在闭包中捕获变量时,添加大括号如何更改生成的 IL 代码?
How adding braces changes the generated IL code when capturing a variable in a closure?
阅读 的答案后,有一件事我不清楚。用户 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
多一对牙套,该片段会更清晰(我认为这足以证明这一点)。
我编译了代码并使用 ILDASM 检查了生成的 IL。事实证明,在这种情况下,两种方法生成的代码没有区别。
.method public hidebysig instance int32 '<X>b__0'() cil managed
{
// Code size 11 (0xb)
.maxstack 1
.locals init ([0] int32 CS[=10=]00)
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[=10=]00)
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'
阅读 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
多一对牙套,该片段会更清晰(我认为这足以证明这一点)。
我编译了代码并使用 ILDASM 检查了生成的 IL。事实证明,在这种情况下,两种方法生成的代码没有区别。
.method public hidebysig instance int32 '<X>b__0'() cil managed
{
// Code size 11 (0xb)
.maxstack 1
.locals init ([0] int32 CS[=10=]00)
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[=10=]00)
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'