OpCodes.Call 字段
定义
重要
一些信息与预发行产品相关,相应产品在发行之前可能会进行重大修改。 对于此处提供的信息,Microsoft 不作任何明示或暗示的担保。
调用传递的方法描述符指示的方法。
public: static initonly System::Reflection::Emit::OpCode Call;
public static readonly System.Reflection.Emit.OpCode Call;
staticval mutable Call : System.Reflection.Emit.OpCode
Public Shared ReadOnly Call As OpCode
字段值
注解
下表列出了指令的十六进制和Microsoft中间语言(MSIL)程序集格式,以及简短的参考摘要:
| Format | 程序集格式 | Description |
|---|---|---|
28 <T> |
叫 methodDesc |
调用由 methodDesc.. 描述的方法。 |
堆栈过渡行为按顺序排列,为:
方法
arg1参数argN被推送到堆栈上。通过
arg1的方法参数argN从堆栈中弹出;通过这些参数执行方法调用,并且控件将传输到方法描述符引用的方法。 完成后,返回值由被调用方方法生成,并发送到调用方。返回值被推送到堆栈上。
指令 call 调用通过指令传递的方法描述符指示的方法。 方法描述符是一个元数据标记,指示要调用的方法以及要传递给该方法的堆栈上的参数的数量、类型和顺序以及要使用的调用约定。 指令call可以紧接 (tailTailcall) 前缀指令,以指定在传输控件之前应释放当前方法状态。 如果调用将控制权转移到比源方法更高的信任方法,则不会释放堆栈帧。 相反,执行会静默地继续,就好像 tail 尚未提供执行一样。 元数据令牌携带足够的信息来确定调用是静态方法、实例方法、虚拟方法还是全局函数。 在所有这些情况下,目标地址完全取决于方法描述符(这与 Callvirt 调用虚拟方法的说明形成鲜明对比),其中目标地址还取决于在之前 Callvirt推送的实例引用的运行时类型。
参数按从左到右的顺序放置在堆栈上。 也就是说,计算第一个参数并将其放置在堆栈上,然后是第二个参数,然后是第三个参数,直到所有必需的参数都按降序排列在堆栈上。 有三个重要的特殊情况:
对实例(或虚拟)方法的调用必须在任何用户可见参数之前推送该实例引用。 实例引用不得为 null 引用。 元数据中携带的签名不包含指针参数列表中的
this条目;而是使用位来指示方法是否需要传递this指针。使用 (而不是
call; )调用虚拟方法callvirt是有效的,这表示使用方法指定的类(而不是从被调用的对象动态指定)解析该方法。请注意,可以使用或
Invoke指令调用call委托callvirt的方法。
SecurityException 如果系统安全性未授予调用方对所调用方法的访问权限,则可能会引发。 当Microsoft中间语言(MSIL)指令转换为本机代码而不是运行时时,可能会进行安全检查。
注释
在值类型上调用 System.Object 的方法时,请考虑将 constrained 前缀与指令一起使用 callvirt ,而不是发出 call 指令。 这样就无需根据值类型是否重写方法发出不同的 IL,从而避免了潜在的版本控制问题。 考虑在对值类型调用接口方法时使用 constrained 前缀,因为实现接口方法的值类型方法可以使用 a 更改 MethodImpl。 操作代码中 Constrained 更详细地介绍了这些问题。
以下 Emit 方法重载可以使用 call 操作码: