C#中的虚拟继承

Virtual Inheritance in C#

当我有一个方法阻止派生 class 覆盖基 class 中定义的虚拟方法时,我对虚拟继承的规则很困惑。这里有一些代码可以更好地解释我的问题:

using System;

namespace ConsoleApplication1
{
    public class A
    {
        public virtual void DoWork()
        {
            Console.WriteLine("A.DoWork()");
        }
    }
    public class B : A
    {
        public override void DoWork()
        {
            Console.WriteLine("B.DoWork()");
        }
    }

    public class C : B
    {
        public sealed override void DoWork()
        {
            Console.WriteLine("C.DoWork()");
        }
    }

    public class D : C
    {
        public new void DoWork()
        {
            Console.WriteLine("D.DoWork()");
        }
    }

    public class MyMainClass
    {
        public static void Main()
        {
            B b = new D();
            b.DoWork();

            C c = new D();
            c.DoWork();

            A a = new D();
            a.DoWork();

            Console.WriteLine("Press any key to exit");
            Console.ReadKey();
        }
    }
}

输出

C.DoWork()
C.DoWork()
C.DoWork()
按任意键退出

的确,如果使用类型 B 的变量来访问 C 的实例 B b = new C(); b.DoWork() 将导致调用 C 的 DoWork() 实现,因为 C 覆盖了 A 的虚拟 DoWork()。

但是,当使用 C、B 或 A 类型的变量访问 D 的实例时,为什么会这样

B b = new D();
C c = new D();
A a = new D();

对它们中的每一个调用 DoWork() 将在 class C?

上调用 DoWork() 的实现

Class D 现在有两个方法叫做 DoWork.

第一个(方法 #1)是在 class A 中定义并在 class C 中重写的虚拟方法。 DC.

继承了这个方法

第二个(方法#2)是在 class D 本身中定义的非虚拟方法。此方法与方法#1 完全不同。

现在,您无法从类型为 D 的变量访问方法 #1,因为方法 #2 hides 方法 #1.

但是,您仍然可以使用 ABC.

类型的变量来访问方法 #1

为了更清楚地说明这一点,这里有一个例子:

D var_d = new D();

B var_b = var_d;

var_d.DoWork(); //This accesses method #2 on an object of type D

var_b.DoWork(); //This accesses method #1 on the same object