I discovered the reason I was getting "Operation could destabilize the runtime" in a DynamicMethod I'm producing, and though I easily fixed it, it left me with a seemingly simple question:
- How do I cast an object reference of type "Object" into a specific type, so that I can call methods from that type on the object reference?
Below is a sample program. When running this, it will crash with an "Operation could destabilize the runtime" exception when compiling the method.
The problem is fixed by just changing the type of the variable being declared to be of type TestClass
instead of Object
, but I still want to know how I can cast the reference to the appropriate type in the code.
In the code I've marked a line with asterixes. What can I emit of code at that point that will make the Object
reference on the stack into a TestClass
reference instead, so that the method call will go through?
Note that I know that it is the method call that produces the problem, if I comment out the lines altogether, it doesn't matter which type the variable is, the method is compiled and executes fine.
Here's the code.
using System;
using System.Reflection.Emit;
namespace ConsoleApplication9
{
public class TestClass
{
public void TestMethod() { }
}
class Program
{
static void Main(string[] args)
{
Type type = typeof(TestClass);
DynamicMethod method = new DynamicMethod("", typeof(Object), null);
ILGenerator il = method.GetILGenerator();
LocalBuilder variable = il.DeclareLocal(typeof(Object));
// Construct object
il.Emit(OpCodes.Newobj, type.GetConstructor(new Type[0]));
il.Emit(OpCodes.Stloc, variable);
// Call Test method
il.Emit(OpCodes.Ldloc, variable);
// ***************************************** what do I do here?
il.Emit(OpCodes.Call, type.GetMethod("TestMethod"));
// Return object
il.Emit(OpCodes.Ldloc, variable);
il.Emit(OpCodes.Ret);
// Create and call delegate
Func<Object> fn = (Func<Object>)method.CreateDelegate(
typeof(Func<Object>));
Object instance = fn();
}
}
}