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 разыменовывается и передается в качестве указателя "this" на methodcallvirt .

  • Если thisType является типом значения и thisType реализует method , то ptr передается без изменений в качестве указателя "this" на инструкцию callmethod для реализации method .thisType

  • Если thisType является типом значения и thisType не реализуется method , то ptr разыменовывая, упакованая и передаваемая в качестве указателя "this" на инструкцию callvirtmethod .

Последний случай может возникать только в том случае, если method он был определен в Object, ValueTypeили Enum и не переопределен .thisType В этом случае бокс вызывает создание копии исходного объекта. Однако, поскольку ни один из методов Object, ValueTypeи Enum не изменяет состояние объекта, этот факт не может быть обнаружен.

Префикс constrained поддерживает генераторы IL, которые создают универсальный код. Обычно инструкция недопустима callvirt для типов значений. Вместо этого компиляторы IL должны эффективно выполнять преобразование this, описанное выше, во время компиляции в зависимости от типа и вызываемого ptr метода. Однако если ptr является универсальным типом, который неизвестен во время компиляции, это преобразование невозможно выполнить во время компиляции.

Код constrained операции позволяет компиляторам IL выполнять вызов виртуальной функции единым способом независимо от того, является ли ptr тип значения или ссылочным типом. Хотя он предназначен для случая, когда thisType является универсальной переменной типа, constrained префикс также работает для необщиных типов и может снизить сложность создания виртуальных вызовов на языках, которые скрывают различие между типами значений и ссылочными типами.

constrained Использование префикса также позволяет избежать потенциальных проблем управления версиями с типами значений. constrained Если префикс не используется, необходимо выдавать разные il-коды в зависимости от того, переопределяет ли тип значения метод System.Object. Например, если тип V значения переопределяет метод Object.ToString(), создается инструкция;V.ToString()callв противном случае box создаются инструкция и callvirtObject.ToString() инструкция. Проблема управления версиями может возникнуть в первом случае, если переопределение будет удалено позже, а во втором — при последующем добавлении переопределения.

Префикс constrained также можно использовать для вызова методов интерфейса для типов значений MethodImpl, так как метод типа значения, реализующий метод интерфейса, можно изменить с помощью . constrained Если префикс не используется, компилятор вынужден выбирать, к какому из методов типа значения привязаться во время компиляции. constrained Использование префикса позволяет MSIL выполнить привязку к методу, который реализует метод интерфейса во время выполнения, а не во время компиляции.

Emit Следующая перегрузка constrained метода может использовать код операции:

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