Почему необходимо загружать каждый аргумент в стек в методе CIL?

StackOverflow https://stackoverflow.com/questions/3471608

Вопрос

в моем приложении мне нужно динамически создать тип, содержащий несколько свойств.Я знаю, что в таких случаях, как этот, необходимо сгенерировать CIL как для методов получения, так и для методов установки свойства с помощью ILGenerator.

Скорее методом проб и ошибок, чем чего-либо еще, я, наконец, пришел к следующему коду, который генерирует для меня метод установки:

MethodBuilder setMethod = customTypeBuilder.DefineMethod(propertyName + "_set", MethodAttributes.Public | MethodAttributes.HideBySig, null, new Type[] {propertyType});
ILGenerator setIlGenerator = setMethod.GetILGenerator();
setIlGenerator.Emit(OpCodes.Ldarg_0);
setIlGenerator.Emit(OpCodes.Ldarg_1);
setIlGenerator.Emit(OpCodes.Stfld, backingField);
setIlGenerator.Emit(OpCodes.Ret);

Код работает достаточно хорошо, но есть одна вещь, которую я в нем не понимаю. Почему необходимо вызывать инструкцию 'Ldarg_0'?

Я знаю, что это ссылается на неявный первый аргумент метода, ссылку "this", поэтому фактическое значение для установщика сохраняется во втором аргументе.Я думал, что должно быть достаточно вызвать только инструкцию Ldarg_1, которая поместила бы второй аргумент в стек (в конце концов, в установщике мне не нужно проверять ссылку "this", поэтому мне не нужно ничего с ней делать), но это приводит к тому, что при попытке установить значение свойства выдается исключение TargetInvocationException.

Спасибо!

Это было полезно?

Решение

Если бы вы не поместили значение "this" в стек, как бы Stfld знаете, поле какого объекта нужно изменить?Возможно, вы пытаетесь написать сеттер, подобный этому:

public int Bizarre
{
    set { otherObject.Field = value; }
}

В основном, Stfld является документированный чтобы в стеке было два значения:один для "цели" нового значения и один для самого значения.Следует признать, что схема перехода стека в ECMA 335 более понятна:

…, obj, value => …,

Другими словами:"stfld удалит два верхних элемента из стека".

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top