2009-08-14 10 views
6

Próbuję uogólniać następujące IL (z reflektorem):„Operacja mogłaby destablize runtime” oraz DynamicMethod z typów wartości

.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 
} 

Jednak, gdy staram się odtworzyć ten IL z 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); 

Otrzymuję wyjątek "Operacja może zdestabilizować środowisko wykonawcze". IL wydaje się identyczny ze mną, jakieś pomysły? ValueSource jest typem wartości, dlatego robię tutaj parametr ref.

EDIT

Oto typ ValueSource:

 public struct ValueSource 
    { 
     public string Value { get; set; } 
    } 
+0

jakaś szansa na (mam nadzieję, że proste) ValueSource więc możemy odtworzyć ...? –

+1

Również - typy wartości powinny być naprawdę niezmienne, co uczyniłoby ten wątek ... –

Odpowiedz

4

Zmienić args do 0/1 (a nie 1/2):

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

ponieważ metoda dynamiczna wydaje do utworzenia jako statyczny, nie do instancji (oryginalna metoda to instancja) - dlatego argumenty są wyłączone przez jeden.

(przepraszam za złą odpowiedź oryginalny - można zostawić drugi kawałek kodu jak true)

+0

Tak, to było to. Następnym razem uczynię moją metodę szablonową statyczną. –