我是编程新手。我学习书籍。有时一些例子会引起问题。求助,关于Habr的解释不是很清楚。在 habr 上找到了一个例子——关于 C# 的第四个问题。
class Program
{
static void Main(string[] args)
{
var x1 = new C();
x1.Print(); //C
B x2 = new C();
x2.Print(); //C
A x3 = new C();
x3.Print(); //A
}
}
class A
{
public void Print()
{
Console.WriteLine("A");
}
}
class B : A
{
new public virtual void Print()
{
Console.WriteLine("B");
}
}
class C : B
{
override public void Print()
{
Console.WriteLine("C");
}
}
Run Code Online (Sandbox Code Playgroud)
解释如下: 在第一次调用中,将显示“C”,因为对于 var 编译器将从表达式的右侧推断对象的类型,这将是类型 C。// 一切都清楚了.
对于第二次调用,还将显示值“C”,因为 CLR 将确定对象的实际类型是 C,并将调用必要的虚方法重载。//所以...
//进一步有点难以理解 在第三种情况下,将显示“A”,因为 B.Print 方法的声明(因此它在 C 中的重载)隐藏了 A.Print 方法。因此,CLR 不会将 B.Print 和 C.Print 视为重载并调用 A 类方法。
我已经在尝试逐步描述堆栈和堆的上下文中发生的事情:
x2:
x3:
1)我的描述是真的吗?如果不是,请用这个例子解释它是如何工作的。
2) 您是否完全同意 Habr 上对答案的解释,或者您会删除/添加/替换某些内容吗?
小智 0
是的,从它的工作原理和链接来看,我的解释是正确的。
运行时(而不是编译器)根据该变量引用的对象的真实类型,确定通过变量调用该方法时要调用哪个版本的方法。(MS Visual C# 循序渐进 9ed,第 12 章使用继承)