OpCodes.Callvirt 字段

定义

对对象调用后期绑定方法,并且将返回值推送到计算堆栈上。

public: static initonly System::Reflection::Emit::OpCode Callvirt;
public static readonly System.Reflection.Emit.OpCode Callvirt;
 staticval mutable Callvirt : System.Reflection.Emit.OpCode
Public Shared ReadOnly Callvirt As OpCode 

字段值

注解

下表列出了指令的十六进制和 Microsoft 中间语言 (MSIL) 程序集格式,以及简短的参考摘要:

格式 程序集格式 说明
6F <T> callvirt method 调用与 obj关联的特定方法。

堆栈过渡行为(按顺序排列)是:

  1. 对象引用 obj 被推送到堆栈上。

  2. 通过 argN 的方法参数arg1被推送到堆栈上。

  3. 通过 argN 和 对象引用obj的方法参数arg1从堆栈中弹出;方法调用是使用这些参数执行的,控件将传输到方法元数据标记引用的方法obj。 完成后,被调用方方法生成一个返回值,并将其发送给调用方。

  4. 返回值将推送到堆栈上。

指令 callvirt 对 对象调用后期绑定方法。 也就是说,该方法是根据 的运行时类型 obj 而不是方法指针中可见的编译时类选择的。 Callvirt 可用于调用虚拟和实例方法。 指令 callvirt 前面 tail 可能紧接 (Tailcall) 前缀,以指定在转移控制权之前应释放当前堆栈帧。 如果调用会将控制权转移到比原始方法信任度更高的方法,则不会释放堆栈帧。

方法元数据令牌提供要调用的方法的名称、类和签名。 与 obj 关联的类是其实例的类。 如果类定义了与指示的方法名称和签名匹配的非静态方法,则调用此方法。 否则,将按顺序检查此类的基类链中的所有类。 如果未找到任何方法,则为错误。

Callvirt 在调用 方法之前,将对象和关联的参数从计算堆栈中弹出。 如果方法具有返回值,则该方法在方法完成时推送到堆栈上。 在被调用方端, obj 参数作为参数 0、 arg1 参数 1 等方式进行访问。

参数按从左到右的顺序放置在堆栈上。 也就是说,计算第一个参数并将其放置在堆栈上,然后是第二个参数,然后第三个参数,直到所有必要的参数以降序排列在堆栈上。 ) 始终需要的callvirt实例引用 obj (必须推送到任何用户可见参数之前。 元数据标记中携带的签名 () 不需要包含此指针的参数列表中的条目。

请注意,也可以使用 指令调用 Call 虚拟方法。

MissingMethodException 如果在与 或其任何基类关联的 obj 类中找不到具有指定名称和签名的非静态方法,则引发 。 当 Microsoft 中间语言 (MSIL) 指令转换为本机代码而不是在运行时时,通常会检测到此情况。

NullReferenceException 如果 obj 为 null,则引发 。

SecurityException 如果系统安全性未授予调用方对调用方法的访问权限,则引发 。 当 CIL 转换为本机代码而不是在运行时时,可能会发生安全检查。

注意

对值类型调用 System.Object 的方法时,请考虑将 constrained 前缀与 指令一起使用 callvirt 。 这样就无需根据值类型是否替代 方法发出不同的 IL,从而避免了潜在的版本控制问题。 在对值类型调用接口方法时,请考虑使用 constrained 前缀,因为可以使用 更改 MethodImpl实现接口方法的值类型方法。 操作码中 Constrained 更详细地描述了这些问题。

以下 Emit 方法重载可以使用 callvirt 操作码:

适用于