I would like to emit a method that has a variable, which I can do. But, I would like to store in that variable a MethodInfo object, which is a reference to a different (non emitted) method.
I could emit the opcodes to call typeof(someClass).GetMethod(...), but it would be more efficient if I could simply load a token for this MethodInfo and bake it directly into the variable.
So, to rephrase, I'm trying to find out of its possible to emit , let's say a "load object" opcode and pass it an object at emit-time that will be loaded onto the stack at runtime. (OpCodes.Ldobj gave some kind of error when I tried this). Or, am I forced to emit opcodes that will do this at runtime?
You can't just load any general object in IL, because there is no way to store it in IL (with the exception of some special types like string
). You could work around that using serialization (for types that support it), but I don't think that's what you want. Also, ldobj
serves quite a different purpose.
But you can do this for MethodInfo
in a way that's very similar to what C# does for the typeof
operator. That means:
ldtoken
instruction to get a RuntimeMethodHandle
MethodBase.GetMethodFromHandle()
to get a MethodBase
MethodInfo
The whole code to generate a method that returns the MethodInfo
could look like this:
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());
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With