c# – 为什么callvirt IL指令会导致虚拟方法中的递归调用?
在这种情况下,IL并不总是将callvirt指令用于虚拟方法:
class MakeMeASandwich{ public override string ToString(){ return base.ToString(); } } 在这种情况下,据说IL将生成调用而不是callvirt,其中生成callvirt以检查变量是否为null,否则抛出NullReferenceException. >如果使用callvirt而不是call,如果堆栈溢出,为什么会发生递归调用? 解决方法
因为那时你的代码完全相同: override string ToString() { return this.ToString(); } 这显然是无限递归,只要给出的方法是ToString最重要的版本.
这个问题无法回答,因为这个问题假设是虚假的.调用指令不检查对接收器的引用是否为空,因此询问调用指令检查为null的原因没有任何意义. 让我重新解释一下,为你提出一些更好的问题:
如果C#代码在虚拟方法上进行非虚拟调用,则编译器必须生成调用,而不是callvirt.这种情况发生的唯一时间是使用base来调用虚方法. 如果C#代码正在进行虚拟调用,那么编译器必须生成一个callvirt. 如果C#代码在非虚拟方法上执行非虚拟调用,则编译器可以选择生成call或callvirt.要么工作. C#编译器通常选择生成callvirt.
不可以.如果已知接收器不为空,则C#编译器可以跳过空检查.例如,如果你说(新的C()).M()用于非虚方法M那么编译器生成一个没有空检查的调用指令是合法的.我们知道(1)该方法不是虚拟的,因此它不必是一个callvirt;我们可以选择是否使用callvirt.我们知道(2)新的C()永远不会为空,所以我们不必生成空检查. 如果C#编译器不知道接收器不为null,那么它将生成一个callvirt,或者它将生成一个空检查,然后调用. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- 有没有办法使用增量更新SQLITE数据库?
- Cocos2dx3.2编写常用UI组件(一)新手指导框GuideLayer
- ruby-on-rails – Docker rails迁移
- xml – XSD架构:如何指定值中的位数?
- 如何用正则匹配后缀名不为.jpg, .css, .js, .html, .htm, .
- ruby-on-rails – ActiveRecord返回每个用户的最新记录(唯一
- Nand-Flash/Nor-Flash存储模块设计
- ajax调用服务器方法,Sesstion过期的处理方法
- 依赖注入 – 我对使用IoC时的界面抽象感到困惑
- 【皮尔逊相关系数】类似于余弦定理的使用(推荐),直接上代码