OpCodes.Constrained Поле
Определение
Важно!
Некоторые сведения относятся к предварительной версии продукта, в которую до выпуска могут быть внесены существенные изменения. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.
Ограничивает тип, в котором выполняется вызов виртуального метода.
public: static initonly System::Reflection::Emit::OpCode Constrained;
public static readonly System.Reflection.Emit.OpCode Constrained;
staticval mutable Constrained : System.Reflection.Emit.OpCode
Public Shared ReadOnly Constrained As OpCode
Значение поля
Комментарии
В следующей таблице перечислены шестнадцатеричные и шестнадцатеричные и промежуточные языки Майкрософт (MSIL) формат сборки, а также краткая справочная сводка:
| Формат | Формат сборки | Описание |
|---|---|---|
FE 16 <T> |
вынужденный. thisType |
Вызов виртуального метода для типа, ограниченного типом, T. |
Префикс constrained разрешен только в инструкции callvirt.
Состояние стека MSIL на этом этапе должно быть следующим:
Управляемый указатель,
ptr, передается на стек. Типptrдолжен быть управляемым указателем (&) дляthisType. Обратите внимание, что это отличается от случая нерекомендаемойcallvirtинструкции, которая ожидает ссылку наthisType.Аргументы метода
arg1черезargNотправляются в стек, как и с нерекомендываемой инструкциейcallvirt.
Префикс constrained предназначен для обеспечения единообразной callvirt инструкций независимо от того, является ли thisType типом значений или ссылочным типом.
Если инструкция callvirtmethod была префиксирована constrainedthisType, инструкция выполняется следующим образом:
Если
thisTypeявляется ссылочным типом (в отличие от типа значения),ptrразыменовывается и передается в качестве указателя наcallvirtmethod.Если
thisTypeявляется типом значения иthisTypeреализуетmethod, тоptrпередается неизмен как указатель на инструкциюcallmethodдля реализацииmethodпоthisType.Если
thisTypeявляется типом значения, аthisTypeне реализуетmethod,ptrразыменовывается, упаковается и передается в качестве указателя на инструкциюcallvirtmethod.
Этот последний случай может возникать только в том случае, если method был определен Object, ValueTypeили Enum, а не переопределен thisType. В этом случае бокс приводит к тому, что копия исходного объекта будет выполнена. Однако, поскольку ни один из методов Object, ValueTypeи Enum изменить состояние объекта, этот факт не может быть обнаружен.
Префикс constrained поддерживает генераторы IL, создающие универсальный код. Как правило, инструкция callvirt недопустима для типов значений. Вместо этого необходимо, чтобы компиляторы IL эффективно выполняли преобразование "this" , описанное выше во время компиляции, в зависимости от типа ptr и вызываемого метода. Однако если ptr является универсальным типом, неизвестным во время компиляции, это преобразование невозможно сделать во время компиляции.
constrained opcode позволяет компиляторам IL вызывать виртуальную функцию в однородном порядке независимо от того, является ли ptr типом значений или ссылочным типом. Хотя он предназначен для случая, когда thisType является универсальной переменной типа, префикс constrained также работает для негенерических типов и может снизить сложность создания виртуальных вызовов на языках, которые скрывают различие между типами значений и ссылочными типами.
Использование префикса constrained также позволяет избежать потенциальных проблем с версиями типов значений. Если префикс constrained не используется, в зависимости от того, переопределяет ли тип значения метод System.Object, должен быть создан другой IL. Например, если тип значения V переопределяет метод Object.ToString(), создается инструкция callV.ToString(); Если это не так, создается инструкция box и callvirtObject.ToString() инструкция. Проблема с управление версиями может возникнуть в предыдущем случае, если переопределение будет удалено позже, и в последнем случае, если переопределение будет добавлено позже.
Префикс constrained также можно использовать для вызова методов интерфейса для типов значений, так как метод типа значения, реализующий метод интерфейса, можно изменить с помощью MethodImpl. Если префикс constrained не используется, компилятор вынужден выбрать методы типа значения для привязки во время компиляции. Использование префикса constrained позволяет MSIL привязаться к методу, реализующего метод интерфейса во время выполнения, а не во время компиляции.
Следующая перегрузка метода Emit может использовать constrained opcode: