Frage

Ich lerne CIL durch meine eigenen Funktionen zur Laufzeit mit Reflection.Emit machen. Ich bin eigentlich überrascht, wie einfach Dinge gewesen, bis jetzt, aber ich habe etwas getroffen, dass ich nicht meinen Weg durch erraten kann, und ich kann nichts in Bezug auf die Dokumentation finden.

Ich versuche, eine Funktion zu erstellen, die einfach druckt eine sehr einfache Klasse I definiert haben. Wenn ich den Code ändern strings zu drucken, sagen wir, es funktioniert, aber es nicht immer laufen, wenn ich eine Instanz meiner Klasse A passieren.

Was komisch ist, ich meine Funktion kann Körper kommentieren und es immer noch nicht mit einem TargetInvocationException. Es muss ganz einfach sein, aber ich kann nicht sehen, was los ist!

class A
{
    public override string  ToString()
    {
        return "AAA!";
    }
}

class Program
{
    static void Main(string[] args)
    {
        DynamicMethod func = new DynamicMethod("func", null, new Type[] { typeof(A) });

        ILGenerator il = func.GetILGenerator();

        //il.Emit(OpCodes.Ldarg_0);
        //il.Emit(OpCodes.Box, typeof(A));
        //il.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(A) }));

        il.Emit(OpCodes.Ret);

        func.Invoke(null, new object[] { new A() });

        Console.Read();
    }
}

Was mache ich so falsch zu machen dies eine Ausnahme auslösen? Warum funktioniert das nur mit meinen Klassen geschehen?

War es hilfreich?

Lösung

Das Problem ist einfach, aber nicht nahe liegend. Für eine Startbox das Argument nicht, wie bereits erwähnt. Aber das eigentliche Problem ist die A-Klasse ist nicht öffentlich. Die Standardbindung für die Invoke-Funktion Sie verwenden (anstatt dem Vollen) ist nur öffentlich Methoden zu finden. Da A eine nicht-öffentliche Klasse ist, bedeutet es es Ihre Funktion zu finden, fehlschlägt (erstaunlich, ich weiß) und schlägt fehl.

Andere Tipps

Es war ziemlich albern eigentlich. Ich verbrachte mehrere Stunden auf diese, aber wenn ich Laurent Etiemble Rat gefolgt und erstellt einen Delegaten die Ausnahme, die ich mir gesagt habe meine Klasse A war nicht öffentlich.

Lösung : Fügen Sie das Schlüsselwort public vor class A. Funktioniert perfekt. I wußte es hatte etwas unglaublich einfach sein.

Erste - Sie sollten nicht die Box Opcode emittierenden seit A eine Klasse ist und muss nicht geboxt werden. Boxen ist nur für Werttypen.

Second - Der Grund, warum es versagt ist, weil die Methode nicht über die Berechtigung der Klasse A zuzugreifen (es ist nicht öffentlich ist). Entweder A public machen oder Sie können den JIT-Compiler anweisen, Sichtbarkeitsprüfungen zu überspringen, indem Sie diese Konstruktor und vorbei true zum skipVisibility Parameter.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top