I've created a very simple function that does the following:
public static object[] ToArray(int ID) {
return new object[4];
}
This is the code that generates the MSIL. Why does this throw the "Operation could destabilize the runtime" exception? I can't spot anything wrong with it; it matches the assembly seen in Reflector/Reflexil perfectly.
// create method
Type arrayType = typeof(object[]);
Type intType = typeof(int);
DynamicMethod dm = new DynamicMethod(methodName, arrayType, new Type[] { intType });
ILGenerator il = dm.GetILGenerator();
// create the array -- object[]
il.Emit(OpCodes.Ldc_I4, 4);
il.Emit(OpCodes.Newarr, typeof(object));
il.Emit(OpCodes.Stloc_0);
// return the array
il.Emit(OpCodes.Ldloc_0);
il.Emit(OpCodes.Ret);
return dm;
object result = dm.Invoke(null, new object[] { 1 });
I found that the new variable was not declared properly.
You need to use the DeclareLocal(typeof(T))
syntax to declare a new local var.
The updated code snippet is as follows:
// create method
Type arrayType = typeof(object[]);
Type intType = typeof(int);
DynamicMethod dm = new DynamicMethod(methodName, arrayType, new Type[] { intType });
ILGenerator il = dm.GetILGenerator();
// create the array -- object[]
LocalBuilder arr = il.DeclareLocal(arrayType);
il.Emit(OpCodes.Ldc_I4, 4);
il.Emit(OpCodes.Newarr, typeof(object));
il.Emit(OpCodes.Stloc, arr); // <-- don't use direct addresses, use refs to LocalBuilder instead
// return the array
il.Emit(OpCodes.Ldloc, arr); // <-- don't use direct addresses, use refs to LocalBuilder instead
il.Emit(OpCodes.Ret);
return dm;
object result = dm.Invoke(null, new object[] { 1 });
Edit: Thanks to Jon Skeet, the final optimized code snippet is as follows:
// create method
Type arrayType = typeof(object[]);
Type intType = typeof(int);
DynamicMethod dm = new DynamicMethod(methodName, arrayType, new Type[] { intType });
ILGenerator il = dm.GetILGenerator();
// create the array -- object[]
LocalBuilder arr = il.DeclareLocal(arrayType);
il.Emit(OpCodes.Ldc_I4, 4);
il.Emit(OpCodes.Newarr, typeof(object));
// return the array
il.Emit(OpCodes.Ret);
return dm;
object result = dm.Invoke(null, new object[] { 1 });
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