OpCodes.Constrained 字段
定义
重要
一些信息与预发行产品相关,相应产品在发行之前可能会进行重大修改。 对于此处提供的信息,Microsoft 不作任何明示或暗示的担保。
约束执行虚拟方法调用的类型。
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
字段值
注解
下表列出了指令的十六进制和Microsoft中间语言(MSIL)程序集格式,以及简短的参考摘要:
| Format | 程序集格式 | 说明 |
|---|---|---|
FE 16 <T> |
约束。 thisType |
对约束为类型 T的类型调用虚拟方法。 |
constrained仅允许在指令中callvirt使用前缀。
此时 MSIL 堆栈的状态必须如下所示:
托管指针
ptr被推送到堆栈上。 类型ptr必须是托管指针 (&) 到thisType。 请注意,这与不受支持的callvirt指令的情况不同,该指令需要引用thisType。方法
argN参数arg1被推送到堆栈上,就像使用不受支持的callvirt指令一样。
前缀 constrained 旨在允许 callvirt 以统一方式进行指令,而不受值类型还是引用类型无关 thisType 。
callvirt
method当指令作为constrainedthisType前缀时,该指令将按如下所示执行:
如果
thisType引用类型(与值类型相反),则会ptr取消引用并作为指向其method的callvirt“this”指针传递。如果
thisType为值类型并thisType实现,method则ptr作为指令的“this”指针callmethod传递,以供method实现。thisType如果
thisType为值类型且thisType未实现method,则ptr取消引用、装箱并作为指向指令的“this”指针callvirtmethod传递。
此最后一种情况只能在定义Object时method发生,ValueType或者Enum不能被thisType重写。 在这种情况下,装箱会导致创建原始对象的副本。 但是,由于没有方法ObjectValueTypeEnum以及修改对象的状态,因此无法检测到此事实。
前缀 constrained 支持创建泛型代码的 IL 生成器。 通常,指令 callvirt 对值类型无效。 相反,IL 编译器在编译时有效地执行上面概述的“this”转换,具体取决于所调用的方法的类型 ptr 和方法。 但是,如果 ptr 泛型类型在编译时未知,则无法在编译时进行此转换。
constrained操作代码允许 IL 编译器以统一的方式调用虚拟函数,而与值ptr类型还是引用类型无关。 尽管它适用于泛型类型变量的情况 thisType , constrained 但前缀也适用于非泛型类型,并可以减少以语言生成虚拟调用的复杂性,这些语言隐藏值类型和引用类型之间的区别。
constrained使用前缀还可以避免值类型的潜在版本控制问题。
constrained如果未使用前缀,则必须发出不同的 IL,具体取决于值类型是否替代 System.Object 的方法。 例如,如果值类型 V 重写 Object.ToString() 方法,则会发出指令 callV.ToString() ;如果没有, box 则会发出指令和 callvirtObject.ToString() 指令。 如果以后删除了替代,则在前一种情况下可能会出现版本控制问题,在后一种情况下,如果添加了替代,则会出现版本控制问题。
constrained前缀还可用于对值类型调用接口方法,因为实现接口方法的值类型方法可以使用 a 更改MethodImpl。
constrained如果未使用前缀,编译器将强制选择要在编译时绑定到的值类型的方法。
constrained使用前缀,MSIL 可以绑定到在运行时(而不是编译时)实现接口方法的方法。
以下 Emit 方法重载可以使用 constrained 操作码: