Поделиться через


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 на этом этапе должно быть следующим:

  1. Управляемый указатель, ptr, передается на стек. Тип ptr должен быть управляемым указателем (&) для thisType. Обратите внимание, что это отличается от случая нерекомендаемой callvirt инструкции, которая ожидает ссылку на thisType.

  2. Аргументы метода 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:

Применяется к