2013-01-11 13 views
5

Kann mir jemand erklären, was vor einem Funktionsaufruf über reflection.emit in den Stack geladen werden muss?Reflection empty stack und Methodenaufruf

Ich habe eine sehr einfache Methode

public static void Execute(string 1, string 2) 

ich die Methode in der folgenden Klasse generieren möchten dynamisch (den Rest vergessen, ich habe sie aussortiert)

public class Test{ 
    public string s1; 

    public void Run(string s2) 
    { 
     MyOtherClass.Execute(s2,s1) 
    } 
} 

Ich habe eine Kopie der oben genannten Test, als Referenz, und ich bemerkte, dass die folgenden Opcodes vor dem "Anruf" emittiert wurden.

  1. ldarg_1
  2. ldarg_0
  3. ldfld

Die Frage ist, was ldarg_0 ist da? Ich brauche nur zwei Argumente für den Aufruf, warum benötigt die CLR ldarg_0, um auf den Stack geschoben zu werden?

+0

Können Sie die umgebende IL bereitstellen? –

Antwort

9

arg.0 enthält this und wird von ldfld string Test:s1 benötigt, um this.s1 auf den Stapel zu schieben.

.method public hidebysig instance void Run(string s2) cil managed 
{ 
    .maxstack 8          // maximum stack size 8 
    ldarg.1           // push argument s2 
    ldarg.0           // push this 
    ldfld string Test::s1       // pop this, push this.s1 
    call void MyOtherClass::Execute(string, string) // call 
    ret            // return 
} 
+0

Danke! Ich weiß, was ich jetzt vermisst habe. – Alwyn

2

Sie müssen die Argumente der Methode in der Reihenfolge der Deklaration und einer Objektreferenz übergeben, wenn die Methode nicht statisch ist. In Ihrem Testfall greifen Sie auf ein Member-Feld zu (s1), also brauchen Sie die this Referenz dafür. Das ist es, was bietet. Der folgende ldfld ruft die this-Referenz auf und verschiebt den Feldwert auf den Auswertungsstapel.