这段代码块的输出对我来说没有意义

Gar*_*ann 7 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();
   }
}
Run Code Online (Sandbox Code Playgroud)

输出是:

B.F
B.F
D.F
D.F
Run Code Online (Sandbox Code Playgroud)

输出不应该是:

D.F
D.F
D.F
D.F
Run Code Online (Sandbox Code Playgroud)

Mar*_*zek 7

使用覆盖和新关键字进行版本控制(C#编程指南)

如果派生类中的方法前面带有new关键字,则该方法被定义为独立于基类中的方法.

所以找你F的方法A,并B没有连接这些从CD,这就是为什么你会得到你所得到的.

在运行时,CLR查找virtual应该从类型开始使用的方法实现,声明的变量最多为类型.对于a.F()并且b.F()它在B.F()声明时停止,因为C.F()是一种不同的方法(因为new).


Fen*_*ndy 0

new public virtual void F()您正在C:B 类中使用。这意味着F()in类CF()in类B是不同的方法。

因此,当您重写C到类时,类中的D方法是从类中覆盖的,而不是。F()DCB

另一个明显的例子可以是这样的:

  C c = new C();
  B b = c;
  b.F();
  c.F();
Run Code Online (Sandbox Code Playgroud)