我想发出一个有变量的方法,我可以做。但是,我想在该变量中存储一个MethodInfo对象,该对象是对不同(非发出)方法的引用。
我可以发出操作码来调用typeof(someClass).GetMethod(...),但是如果我可以简单地为这个MethodInfo加载一个标记并将其直接烘焙到变量中,效率会更高。
所以,重新说一下,我试图找出它的可能发射,让我们说一个“加载对象”操作码,并在发射时传递一个对象,该对象将在运行时加载到堆栈中。 (当我尝试这个时,OpCodes.Ldobj出现了一些错误)。或者,我是否被强制发出将在运行时执行此操作的操作码?
答案 0 :(得分:9)
你不能只在IL中加载任何通用对象,因为没有办法将它存储在IL中(除了string
之类的一些特殊类型)。您可以使用序列化(对于支持它的类型)来解决这个问题,但我认为这不是您想要的。此外,ldobj
的用途完全不同。
但是你可以以MethodInfo
的方式执行此操作,其方式与C#对typeof
运算符的方式非常相似。这意味着:
ldtoken
指令获取RuntimeMethodHandle
MethodBase.GetMethodFromHandle()
以获取MethodBase
MethodInfo
生成返回MethodInfo
的方法的整个代码可能如下所示:
MethodInfo loadedMethod = …;
var getMethodMethod = typeof(MethodBase).GetMethod(
"GetMethodFromHandle", new[] { typeof(RuntimeMethodHandle) });
var createdMethod = new DynamicMethod(
"GetMethodInfo", typeof(MethodInfo), Type.EmptyTypes);
var il = createdMethod.GetILGenerator();
il.Emit(OpCodes.Ldtoken, loadedMethod);
il.Emit(OpCodes.Call, getMethodMethod);
il.Emit(OpCodes.Castclass, typeof(MethodInfo));
il.Emit(OpCodes.Ret);
var func = (Func<MethodInfo>)createdMethod.CreateDelegate(typeof(Func<MethodInfo>));
Console.WriteLine(func());