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
типом значений или ссылочным типом.
Если инструкция callvirt
method
была префиксирована constrained
thisType
, инструкция выполняется следующим образом:
Если
thisType
является ссылочным типом (в отличие от типа значения),ptr
разыменовывается и передается в качестве указателя наcallvirt
method
.Если
thisType
является типом значения иthisType
реализуетmethod
, тоptr
передается неизмен как указатель на инструкциюcall
method
для реализацииmethod
поthisType
.Если
thisType
является типом значения, аthisType
не реализуетmethod
,ptr
разыменовывается, упаковается и передается в качестве указателя на инструкциюcallvirt
method
.
Этот последний случай может возникать только в том случае, если 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(), создается инструкция call
V.ToString()
; Если это не так, создается инструкция box
и callvirt
Object.ToString()
инструкция. Проблема с управление версиями может возникнуть в предыдущем случае, если переопределение будет удалено позже, и в последнем случае, если переопределение будет добавлено позже.
Префикс constrained
также можно использовать для вызова методов интерфейса для типов значений, так как метод типа значения, реализующий метод интерфейса, можно изменить с помощью MethodImpl
. Если префикс constrained
не используется, компилятор вынужден выбрать методы типа значения для привязки во время компиляции. Использование префикса constrained
позволяет MSIL привязаться к методу, реализующего метод интерфейса во время выполнения, а не во время компиляции.
Следующая перегрузка метода Emit может использовать constrained
opcode: