c# - 这个代码块的输出对我来说没有意义

标签 c# virtual-functions

所有调用实例的运行时类型都是 D,因此 F() 的所有调用都应该是 D 中声明的 F() 方法。

using System;
class A
{
   public virtual void F() { Console.WriteLine("A.F"); }
}
class B: A
{
   public override void F() { Console.WriteLine("B.F"); }
}
class C: B
{
   new public virtual void F() { Console.WriteLine("C.F"); }
}
class D: C
{
   public override void F() { Console.WriteLine("D.F"); }
}
class Test
{
   static void Main() {
      D d = new D();
      A a = d;
      B b = d;
      C c = d;
      a.F();
      b.F();
      c.F();
      d.F();
   }
}

输出是:

B.F
B.F
D.F
D.F

输出不应该是:

D.F
D.F
D.F
D.F

最佳答案

Versioning with the Override and New Keywords (C# Programming Guide)

If the method in the derived class is preceded with the new keyword, the method is defined as being independent of the method in the base class.

因此您是 AB 中的 F 方法与 中的方法没有连接 CD,这就是你得到你所得到的原因。

在运行时,CLR 会寻找virtual 方法实现,该方法实现应从类型开始使用,变量声明为实际类型。对于 a.F()b.F() 它在 B.F() 声明处停止,因为 C.F() 是一个不同的方法(因为 new)。

关于c# - 这个代码块的输出对我来说没有意义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15872454/

相关文章:

c# - 如何最小起订量使用工作单元和存储库模式的简单添加功能

c# - 为什么我的触发器以空白控件结束?

C++ 虚函数表现怪异

c++ - C++中调用虚函数的时间复杂度

c++ - 充斥着标识符错误

c# - 我可以使用重复检测来取消计划的 Azure 服务总线消息吗?

c# - 来自 System.IO.Compression 和异步 I/O 的 ZipFile 和 ZipArchive 类

c# - Form.ShowDialog(IWin32Window) 是否应该与任何窗口句柄一起使用?

c++ - 为什么通过基类指针初始化派生类与通过派生类指针初始化不同?

c++ - 派生类的成员函数是否继承了基类的虚拟性?