Warum fügt der Compiler einen zusätzlichen Parameter für Delegierte hinzu, wenn keine Schließung vorliegt?

Ich habe mit @ gespiedelegates und bemerkte, dass, wenn ich ein @ erstellFunc<int,int,int> wie im folgenden Beispiel:

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

Die Signatur der vom Compiler generierten Methode entspricht nicht meinen Erwartungen:

Wie Sie sehen können, benötigt es ein Objekt für den ersten Parameter. Aber wenn es eine Schließung gibt:

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

Alles funktioniert wie erwartet:

Dies ist der IL-Code für die Methode mit dem zusätzlichen Parameter:

    .method private hidebysig static int32  '<Main>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::'<Main>b__0'

Es scheint, dass der ParameterA_0 wird nicht einmal verwendet. Also, was ist der Zweck desobject Parameter im ersten Fall? Warum wird es nicht hinzugefügt, wenn ein Abschluss vorliegt?

Hinweis Wenn Sie eine bessere Idee für den Titel haben, können Sie diese gerne bearbeiten.

Anmerkung 2 Ich habe den ersten Code in beiden kompiliertDebug undRelease Modi gab es keinen Unterschied. Aber ich kompilierte den zweiten Platz inDebug -Modus, um ein Schließverhalten zu erhalten, da die lokale Variable in @ optimiert wiRelease mode.

Notiz 3 Ich benutzeVisual Studio 2014 CTP.

Bearbeiten Dies ist der generierte Code fürMain im ersten Fall

.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<int32,int32,int32> func1)
  IL_0000:  nop
  IL_0001:  ldsfld     class [mscorlib]System.Func`3<int32,int32,int32> ConsoleApplication9.Program::'CS
.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<int32,int32,int32> func1)
  IL_0000:  nop
  IL_0001:  ldsfld     class [mscorlib]System.Func`3<int32,int32,int32> 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::'<Main>b__0'(object,
                                                                       int32,
                                                                       int32)
  IL_0011:  newobj     instance void class [mscorlib]System.Func`3<int32,int32,int32>::.ctor(object,
                                                                                             native int)
  IL_0016:  dup
  IL_0017:  stsfld     class [mscorlib]System.Func`3<int32,int32,int32> ConsoleApplication9.Program::'CS$<>9__CachedAnonymousMethodDelegate1'
  IL_001c:  stloc.0
  IL_001d:  ret
} // end of method Program::Main
lt;>9__CachedAnonymousMethodDelegate1' IL_0006: dup IL_0007: brtrue.s IL_001c IL_0009: pop IL_000a: ldnull IL_000b: ldftn int32 ConsoleApplication9.Program::'<Main>b__0'(object, int32, int32) IL_0011: newobj instance void class [mscorlib]System.Func`3<int32,int32,int32>::.ctor(object, native int) IL_0016: dup IL_0017: stsfld class [mscorlib]System.Func`3<int32,int32,int32> ConsoleApplication9.Program::'CS
.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<int32,int32,int32> func1)
  IL_0000:  nop
  IL_0001:  ldsfld     class [mscorlib]System.Func`3<int32,int32,int32> 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::'<Main>b__0'(object,
                                                                       int32,
                                                                       int32)
  IL_0011:  newobj     instance void class [mscorlib]System.Func`3<int32,int32,int32>::.ctor(object,
                                                                                             native int)
  IL_0016:  dup
  IL_0017:  stsfld     class [mscorlib]System.Func`3<int32,int32,int32> ConsoleApplication9.Program::'CS$<>9__CachedAnonymousMethodDelegate1'
  IL_001c:  stloc.0
  IL_001d:  ret
} // end of method Program::Main
lt;>9__CachedAnonymousMethodDelegate1' IL_001c: stloc.0 IL_001d: ret } // end of method Program::Main

Antworten auf die Frage(2)

Ihre Antwort auf die Frage