为什么编译器在没有闭包时为委托添加额外的参数?

我正在与delegates一起玩,并注意到当我创建一个Func如下例所示:

 Func func1 = (x, y) => x * y; 

编译器生成的方法的签名不是我所期望的:

在此处输入图像描述

正如您所看到的,它需要一个对象作为它的第一个参数。 但是当有一个关闭时:

 int z = 10; Func func1 = (x, y) => x * y * z; 

一切都按预期工作:

在此处输入图像描述

这是带有额外参数的方法的IL代码:

  .method private hidebysig static int32 'b__0'(object A_0, int32 x, int32 y) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) // Code size 8 (0x8) .maxstack 2 .locals init ([0] int32 V_0) IL_0000: ldarg.1 IL_0001: ldarg.2 IL_0002: mul IL_0003: stloc.0 IL_0004: br.s IL_0006 IL_0006: ldloc.0 IL_0007: ret } // end of method Program::'b__0' 

似乎甚至没有使用参数A_0 。 那么,第一种情况下object参数的目的是什么? 当有关闭时为什么不添加它?

注意:如果您对标题有更好的了解,请随时编辑。

注2:我在DebugRelease模式下编译了第一个代码,没有区别。 但是我在Debug模式下编译第二个以获得闭包行为,因为它在Release模式下优化了局部变量。

注3:我正在使用Visual Studio 2014 CTP

编辑:这是第一种情况下Main的生成代码:

 .method private hidebysig static void Main(string[] args) cil managed { .entrypoint // Code size 30 (0x1e) .maxstack 2 .locals init ([0] class [mscorlib]System.Func`3 func1) IL_0000: nop IL_0001: ldsfld class [mscorlib]System.Func`3 ConsoleApplication9.Program::'CS$9__CachedAnonymousMethodDelegate1' IL_0006: dup IL_0007: brtrue.s IL_001c IL_0009: pop IL_000a: ldnull IL_000b: ldftn int32 ConsoleApplication9.Program::'b__0'(object, int32, int32) IL_0011: newobj instance void class [mscorlib]System.Func`3::.ctor(object, native int) IL_0016: dup IL_0017: stsfld class [mscorlib]System.Func`3 ConsoleApplication9.Program::'CS$9__CachedAnonymousMethodDelegate1' IL_001c: stloc.0 IL_001d: ret } // end of method Program::Main 

虽然这看起来非常令人惊讶,但快速搜索表明这是出于性能原因。

在关于它的bug报告中 ,它指出那些没有隐式的委托比那些有隐式的委托慢得多,因为没有隐式的委托需要做一些复杂的参数改组。委托被调用:

假设你调用func1(1, 2) 。 这看起来像(伪代码,而不是CIL)

 push func1 push 1 push 2 call Func<,,>::Invoke 

当知道这个func1被绑定到一个带有两个int值的静态函数时,它需要执行相应的两个

 push arg.1 push arg.2 call method 

要么

 arg.0 = arg.1 arg.1 = arg.2 jmp method 

而当已知func1被绑定到一个静态函数时,取值为null和两个int值,它只需要执行相当于

 arg.0 = null jmp method 

因为环境已经完美地设置为输入引用类型和两个int值的函数。

是的,这是一个微观优化,通常无关紧要,但它是每个人都受益的,包括那些重要的情况。