IL为调用函数提供了两个语句,即call和callvirt.调用用于调用非虚函数或静态函数或编译器不希望对引用进行空检查的任何函数.
callvirt用于调用虚函数,也调用非虚函数,因为编译器在运行时对引用进行空检查.
现在,当通过C#进行CLR时,我发现了以下示例.
internal class SomeClass
{
public override String ToString()
{
return base.ToString();
}
}
现在ToString()是虚函数,但是编译器为它生成了调用指令.但杰弗里提到为什么没有生成callvirt的原因是因为在这种情况下ToString()会被递归调用并导致*异常,我试图理解,但无法围绕这个想法?任何人都可以解释为什么它会导致递归调用?
谢谢..
解决方法:
据我所知,如果编译器生成callvirt,会发生*异常,因为:
有些代码调用someclass类型的对象的ToString,它继承自类对象.
* somclass“方法的ToString调用它的基类的ToString方法,它是对象.
如果此调用是虚拟的,则不会导致从类对象调用ToString,而是调用实际类(即SomeClass)的ToString.
然后你就会处于一个不定式的循环中,因为现在整个事情将从新的开始.