"Operation can destabilize runtime" and DynamicMethod with type values

I am trying to generalize the following IL (from Reflector):

.method private hidebysig instance void SetValue(valuetype Test.TestFixture/ValueSource& thing, string 'value') cil managed { .maxstack 8 L_0000: nop L_0001: ldarg.1 L_0002: ldarg.2 L_0003: call instance void Test.TestFixture/ValueSource::set_Value(string) L_0008: nop L_0009: ret } 

However, when I try to reproduce this IL with DynamicMethod:

  [Test] public void Test_with_DynamicMethod() { var sourceType = typeof(ValueSource); PropertyInfo property = sourceType.GetProperty("Value"); var setter = property.GetSetMethod(true); var method = new DynamicMethod("Set" + property.Name, null, new[] { sourceType.MakeByRefType(), typeof(string) }, true); var gen = method.GetILGenerator(); gen.Emit(OpCodes.Ldarg_1); // Load input to stack gen.Emit(OpCodes.Ldarg_2); // Load value to stack gen.Emit(OpCodes.Call, setter); // Call the setter method gen.Emit(OpCodes.Ret); var result = (SetValueDelegate)method.CreateDelegate(typeof(SetValueDelegate)); var source = new ValueSource(); result(ref source, "hello"); source.Value.ShouldEqual("hello"); } public delegate void SetValueDelegate(ref ValueSource source, string value); 

I get an exception: "An operation can destabilize runtime." IL seems identical to me, any ideas? ValueSource is a value type, so I am making the ref parameter here.

EDIT

Here's the type of ValueSource:

  public struct ValueSource { public string Value { get; set; } } 
+6
c # cil
source share
1 answer

Change the arguments to 0/1 (not 1/2):

  gen.Emit(OpCodes.Ldarg_0); // Load input to stack gen.Emit(OpCodes.Ldarg_1); // Load value to stack 

because the dynamic method seems to be created as a static and not an instance (your original method is an instance) - therefore, the arguments are disabled by one.

(sorry for the original wrong answer - you can leave another bit of code as true )

+4
source share

All Articles