2012-03-27 6 views
3

Vor nicht allzu langer Zeit begann ich zu lernen, System.Reflection.Emit Namespace zu verwenden. Ich versuche jetzt diesen Code zu übersetzen, von ILGenerator zu verwenden:Wie übersetzt man neue Objekte?

MyClass c = new MyClass("MyClass"); 
c.Do(":D"); 

Für dieses Stück Code, den ich habe drei Fragen: Wie Objekt erstellen? Wie man Contructor aufruft und wie man Methode der Klasse nennt? Bitte helfen Sie.

+4

Der beste Weg zu lernen, was hinter den Kulissen tun C# ist, ist an der IL zu sehen, dass es für Ihren Code generiert. Ich nehme an, dass Sie wissen, wie man eine Disassemblierung im Debugger betrachtet, oder? – dasblinkenlight

+0

ok. Danke euch allen. – user35443

Antwort

3

Hier ist ein vollständiges Beispiel, das den erforderlichen IL-Code zeigt.

Sie können dies testen in LINQPad:

void Main() 
{ 
    // Manual test first 
    MyClass c = new MyClass("MyClass"); 
    c.Do(":D"); 

    var method = new DynamicMethod("dummy", null, Type.EmptyTypes); 
    var il = method.GetILGenerator(); 

    // <stack> = new MyClass("MyClass"); 
    il.Emit(OpCodes.Ldstr, "MyClass"); 
    il.Emit(OpCodes.Newobj, typeof(MyClass).GetConstructor(new[] { typeof(string) })); 

    // <stack>.Do(":D"); 
    il.Emit(OpCodes.Ldstr, ":D"); 
    il.Emit(OpCodes.Call, typeof(MyClass).GetMethod("Do", new[] { typeof(string) })); 

    // return; 
    il.Emit(OpCodes.Ret); 

    var action = (Action)method.CreateDelegate(typeof(Action)); 
    action(); 
} 

public class MyClass 
{ 
    public MyClass(string text) 
    { 
     Console.WriteLine("MyClass(" + text + ")"); 
    } 

    public void Do(string text) 
    { 
     Console.WriteLine("Do(" + text + ")"); 
    } 
} 

Ausgang:

MyClass(MyClass) 
Do(:D) 
MyClass(MyClass) 
Do(:D) 

Im Übrigen können Sie LINQPad verwenden halten, den IL-Code für ein bestimmtes Beispiel zu erhalten. Lassen Sie mich den IL-Teil des obigen Beispiels ausgeschnitten, so (ich auch die Klasse entfernt, es ist die gleiche Klasse):

void Main() 
{ 
    MyClass c = new MyClass("MyClass"); 
    c.Do(":D"); 
} 

Durch diesen Code ausgeführt wird, und dann unter Verwendung des IL-Registerkarte des Ausgangs

LINQPad IL Output

die beiden Anweisungen stloc.0 und ldloc.0 ist die Variable im Code: Sie können den generierten Code sehen.

Die IL emittieren I zunächst zu diesem Stück Code verwendet:

new MyClass("MyClass").Do(":D"); 

dh. keine Variable, nur temporäre Speicher auf dem Stapel, und in der Tat:

LINQPad IL output #2