CLR via C#第六章:CLR调用虚方法、属性和事件

任何方法包括一个名称、一个签名和一个返回值。

理论上即使方法名和签名相同,只要返回值不一样。这也算是两个不同的方法。但是,实际上,只有IL汇编语言利用了这个特点。(同名方法,必须要求参数不一致,如果只是返回值不一样是不会通过编译的)

编译器在编译代码时,会在生成的程序集的方法表中记录方法是实例方法、静态方法还是虚方法的。对于不同的方法,CLR会调用不同的IL指令来执行方法的。

        此IL指令可以调用静态方法、实例方法和虚方法,使用这个指令时,如果是静态方法,必须指明了是哪个类型。如果是实例方法和虚方法时,就必须指定引用了哪一个对象。然后回根据这个对象的类型去调用方法。call指令不会去检查这个对象是否是null,只要提供类型就行了。

  • call
  • callvirt

       此IL指令可以调用实例方法和虚方法。 使用这个指令时,也必须指定引用了一个对象的变量。而且,不同与call指令的是,callvirt指令会检查这个对象的实际类型(多态时会有影响的)。并且,此指令会额外检查这个对象是否为null(为了确定实际类型)。

可以看出来,其实callvirt指令的效率是比call效率要差

注意:

  • 将某个方法定义为非虚方法后,将来永远不要把他更改为虚方法。这是因为某些编译器会用call而不是callvirt来调用非虚方法。如果将方法从非虚方法改为虚方法后。同时没有重新编译引用代码,就会以非虚方式调用虚方法,造成应用程序的行为无法预料,如果引用代码是C#写的,这就不是一个问题,因为C#使用callvirt指令调用所有的实例方法。
  • 无论是call还是callvirt指令调用实例方法还是虚方法,这些方法通常接收一个隐藏的this实参作为方法的第一个参数。this实参引用的是要操作的对象。
  • 定义一个类型时,尽量避免少使用虚方法。有以下几点原因
  1.  调用虚方法比调用实例方法的速度要慢
  2. JIT编译器不能内嵌虚方法
  3. 使用虚方法会使组件的版本控制变得脆弱
  4. 定义一个基类型时,经常需要提供一组重载的简便方法。如果希望这些方法是多态的,最好的方法是就是使最复杂的方法成为虚方法,使所有重载的方法成为非虚方法。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值