Dies ist eine Lernübung. Ich habe eine Methode erstellt, die ein Foo und eine Zeichenfolge verwendet und die A-Eigenschaft festlegt. Ich habe die Reflektordemontage verwendet, um den folgenden Code zu emittieren. Die Demontage wie folgt aussieht:DynamicMethod erstellen, um einer Eigenschaft einen Wert zuzuweisen?
.method private hidebysig static void Spork(class ConsoleTesting.Foo f, string 'value') cil managed
{
.maxstack 8
L_0000: ldarg.0
L_0001: ldarg.1
L_0002: callvirt instance void ConsoleTesting.Foo::set_A(string)
L_0007: ret
}
Ok, so modellierte ich meine emit Code danach:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Reflection.Emit;
namespace ConsoleTesting
{
class Foo
{
public string A { get; set; }
}
class Program
{
static Action<Foo, string> GenMethodAssignment(string propName)
{
MethodInfo setMethod = typeof(Foo).GetMethod("get_" + propName);
if (setMethod == null)
throw new InvalidOperationException("no property setter available");
Type[] argTypes = new Type[] { typeof(Foo), typeof(String) };
DynamicMethod method = new DynamicMethod("__dynamicMethod_Set_" + propName, null, argTypes, typeof(Program));
ILGenerator IL = method.GetILGenerator();
IL.Emit(OpCodes.Ldarg_0);
IL.Emit(OpCodes.Ldarg_1);
IL.Emit(OpCodes.Callvirt, setMethod);
IL.Emit(OpCodes.Ret);
method.DefineParameter(1, ParameterAttributes.In, "instance");
method.DefineParameter(2, ParameterAttributes.In, "value");
Action<Foo, string> retval = (Action<Foo, string>)method.CreateDelegate(typeof(Action<Foo, string>));
return retval;
}
static void Main(string[] args)
{
Foo f = new Foo();
var meth = GenMethodAssignment("A");
meth(f, "jason");
Console.ReadLine();
}
}
ich diese Ausnahme erhalten:
JIT Compiler encountered an internal limitation.
Was die krunk tut, gemein und wie repariere ich es?
EDIT:
Ich dachte, vielleicht ist es, weil die Zielmethode ist privat, aber ich bin mir nicht so sicher. Von der DynamicMethod MSDN page:
Das folgende Codebeispiel erstellt eine DynamicMethod, die logisch einem Typ zugeordnet ist. Diese Zuordnung ermöglicht den Zugriff auf die privaten Member dieses Typs.
Sie greifen auf die Methode "get_" zu; Ist das nur ein Tippfehler in deinem Beitrag? Beachten Sie, dass Sie auf die Eigenschaft nach Name zugreifen können und die GetSetMethod() -Methode für das PropertyInfo-Objekt verwenden können. Auf diese Weise verlassen Sie sich nicht auf die C# -Konvention von "get_" und "set_". –
Ich korrigierte gerade einen Tippfehler. Die IL enthielt AStr anstelle von A, weil ich die Eigenschaft für den Zweck dieses Beitrags umbenannt hatte. – Amy
Ah, ich habe den ersten Satz Ihres Kommentars falsch interpretiert. Du hast absolut recht. – Amy