C#继承和虚函数混淆

Nar*_*ehM 6 c# virtual inheritance

今天我提出了一个有趣的问题.我注意到以下代码:

class A
{
    public A()
    {
        Print();
    }
    public virtual void Print()
    {
        Console.WriteLine("Print in A");
    }
}

class B : A
{
    public B()
    {
        Print();
    }

    public override void Print()
    {
        Console.WriteLine("Print in B");
    }
}

class Program
{
    static void Main(string[] args)
    {
        A a = new B();
    }
}
Run Code Online (Sandbox Code Playgroud)

打印

Print in B
Print in B
Run Code Online (Sandbox Code Playgroud)

我想知道它为什么两次打印"B中打印".

Jon*_*eet 11

我想知道它为什么两次打印"B中打印".

您在同一个对象上调用两次虚拟方法.该对象是B即使在A构造函数中的实例,因此将调用重写的方法.(我相信在C++中,对于基类构造函数执行,对象只"变成"子类的一个实例,就多态性而言.)

请注意,这意味着在派生类的构造函数体有机会执行之前,将执行从构造函数调用的重写方法.这很危险.你应该几乎从不从构造函数中调用抽象或虚方法,正是出于这个原因.

编辑:注意,当你没有提供另一个构造函数调用"链"使用: this(...): base(...)在构造函数声明中时,它等同于使用: base().所以B构造函数相当于:

public B() : base()
{
    Print();
}
Run Code Online (Sandbox Code Playgroud)

有关构造函数链接的更多信息,请参阅有关该主题的文章.