ich spiele grad etwas mit dem Reflection.Emit-Namespace. Mein ziel ist eine bereits existierende Methode komplett nachzubauen.
Dazu hole ich mir den CIL-Code einer existierenden Methode mit GetType() GetMethod(...) GetMethodBody() GetILAsByteArray() und parse ihn zurück in eine Abfolge von OpCodes & passenden Operanden. Aus diesen baue ich dann mit ILGenerator und dem Emit(...) eine neue DynamicMethod, die ich dann aufrufe und hoffe, dass genau das selbe passiert, wie bei der Ausgangsmethode =).
Für eine Methode wie
static int foo(int x) {return x*4 +2;}
static int foo(int x) {return bar(x);}
Anscheinend hakt das mit dem Call-Befehl Ein-/Auslesen irgendwie.
Folgende Beobachtungen habe ich gemacht:
- Der Operand des Call-Befehls aus der Ausgangsmethode ist eine Zahl und entspricht dem MethodInfo.MetadataToken der bar-Methode.
- Wenn ich denn Call Befehl per Hand emittiere, also mit
dann klappt es auch.
Emit(OpCodes.Call, barMethodInfo);
Nur ein
Emit(OpCodes.Call, barMethodInfo.MetadataToken);
Gibt es eine Möglichkeit aus dem MetadataToken an die MethodInfo zu kommen? Bzw. irgendwie anders das zum Laufen zu bekommen?
Ich hoffe, ich konnte mein Anliegen rüberbringen, falls nicht: nachfragen
beste Grüße
zommi
PS: Mit Mono.Cecil geht das vielleicht irgendwie. Aber ich wollte es schon gern mit dem Standard-Framework versuchen.
PS2: Wenn ich auch mal in den emittierten CIL-Code blicken könnte, wäre das auch schön. Aber ein GetILAsByteArray() klappt bei einer DynamicMethod bringt immer nen Fehler.