IL提供了两个用于调用函数的语句,即call和callvirt。调用用于调用非虚拟或静态函数或编译器不想对引用进行空检查的任何函数。
callvirt用于调用虚拟函数,非虚拟函数也被调用,因为编译器会在运行时对引用进行空检查。
现在,当通过C#通过CLR时,我发现了以下示例。
internal class SomeClass
{
public override String ToString()
{
return base.ToString();
}
}
Run Code Online (Sandbox Code Playgroud)
现在ToString()是虚拟函数,但是编译器可以正常生成调用指令,但是Jeffrey提到了为什么不生成callvirt的原因,因为在这种情况下ToString()将被递归调用并将导致StackOverFlow异常,我试图理解,但无法将这个想法包住心?谁能解释为什么会导致递归调用?
谢谢..
据我所知,如果编译器生成 callvirt,就会发生 stackoverflow 异常,因为:
某些代码调用从类object继承的someclass类型的对象的 ToString 。*somclass" 方法的 ToString 调用其基类object的 ToString 方法。
如果此调用是虚拟的,则不会导致从类对象调用 ToString ,而是调用实际类(即SomeClass)的 ToString 。
然后你就会陷入不定式循环,因为整个事情将从现在开始。
| 归档时间: |
|
| 查看次数: |
2958 次 |
| 最近记录: |