IL 提供了两种调用函数的语句,即 call 和 callvirt。 Call 用于调用非虚拟或静态函数或编译器不想对引用进行空检查的任何函数。
callvirt 用于调用虚函数,非虚函数也被调用,因为编译器在运行时对引用进行空检查。
现在,在通过 C# 处理 CLR 时,我发现了以下示例。
internal class SomeClass
{
public override String ToString()
{
return base.ToString();
}
}
现在 ToString() 是虚函数,但是编译器为它生成调用指令没问题。但是 Jeffrey 提到为什么不生成 callvirt 的原因是因为在那种情况下 ToString() 将被递归调用并导致StackOverFlow 异常,我试图理解但无法理解这个想法?谁能解释一下为什么会导致递归调用?
谢谢..
最佳答案
据我所知,如果编译器生成 callvirt,则会发生 stackoverflow 异常,因为:
某些代码调用了 someclass 类型对象的 ToString,它继承自 object 类。 *somclass"方法的 ToString 调用它的基类 object 的 ToString 方法。
如果这个调用是虚拟的,它不会导致从类object调用ToString,而是调用实际类的ToString(这是SomeClass).
然后你会进入一个无限循环,因为整个事情将从新开始。
关于c# - 使用 callvirt 调用 base.ToString() 如何导致 StackOverflow 异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2227488/