“Операция могла дестабилизировать время выполнения” и DynamicMethod с типами значения

Я пытаюсь обобщить следующий IL (из Отражателя):

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

Однако, когда я пытаюсь воспроизвести этот IL с 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);

Я добираюсь, исключение "Операции могло дестабилизировать время выполнения". IL кажется идентичным мне, каким-либо идеям? ValueSource является типом значения, который является, почему я делаю касательно параметра здесь.

Править

Вот тип ValueSource:

public struct ValueSource
{
   public string Value { get; set; }
}
6
задан Rookian 14 November 2019 в 11:56
поделиться

1 ответ

Измените аргументы на 0/1 (не 1/2):

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

потому что динамический метод создается как статический, а не как экземпляр (ваш исходный метод - экземпляр) - следовательно аргументы отличаются на единицу.

(извините за исходный неправильный ответ - вы можете оставить другой бит кода как true )

4
ответ дан 17 December 2019 в 07:07
поделиться
Другие вопросы по тегам:

Похожие вопросы: