IL中call与callvirt的区别及其对Equal操作的影响

本文介绍了IL中的call和callvirt指令的区别,call指令假定对象非null并使用声明类型的方法,而callvirt会检查对象是否为null并找到实际类型的方法。在对象判等操作中,C#使用call调用运算符重载的static方法,可能导致意外的结果,因此在使用时需注意声明类型的影响。
摘要由CSDN通过智能技术生成

《CLR via C#》中是这样描述它们的:

编译器在生成方法时会在方法定义表中写入该方法的记录项,每个记录项中有一组标志指令方法是静态方法、实例方法还是虚方法,如下图:


生成IL代码时,编译器会根据这些标志,判断应如何生成IL代码(是使用call还是callvirt)。

call (静态/前期绑定)

该IL指令可调用静态方法、实例方法和虚方法。用call指令调用静态方法,必须指定方法的定义类型。用call指令调用实例方法或虚方法,必须指定引用了对象的变量。call指令假定该变量不为null(在用call指令调用实例和虚方法时,JIT会假定变量不为null,不会生成代码来验证该变量的值是否为null)。换言之,变量本身的类型指明了方法的定义类型。如果变量的类型没有定义该方法,就检查基类型来查找匹配方法。call指令经常用于以非虚方式调用虚方法(意思是如果子类重写的基类的方法,而变量是基类,那么调用的便是基类中该方法的实现,而不是子类中该方法的实现)。请看下面:

首先实现了两个类Animal,Dog继承自Animal并重写了GetName方法。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值