为什么 SecondChild class 的覆盖方法没有被调用两次?

Why override method of SecondChild class is not getting invoked twice?

我不清楚为什么 SecondChild class DoSomethingChild class 初始化时没有被再次调用。

class Parent
{
    public Parent()
    {
       DoSomething();
    }
    protected virtual  void DoSomething()
    {
        Console.WriteLine("Parent Method");
    }
}
class Child : Parent
{
    private string foo;

    public Child()
    {
        foo = "HELLO";
    }
    protected override void DoSomething()
    {
       Console.WriteLine(foo.ToLower());
    }
}
class SecondChild : Parent
{
    public SecondChild()
    {
        var c = new Child();
    }

    protected override void DoSomething()
    {
        Console.WriteLine("In second Child");
    }
}
class Program
{
    static void Main(string[] args)
    {
        SecondChild c = new SecondChild();
        Console.ReadLine();
    }
}

我原以为 SecondChildDoSomething() 会在这里被调用两次,但 Child class DoSomething() 却被调用了 NullException.

我稍微调整了你的定义:

class Parent
{
    protected string foo;
    public Parent()
    {
        foo = "Parent1";
        DoSomething();
        foo = "Parent2";
    }
    protected virtual void DoSomething()
    {
        Console.WriteLine("Parent Method");
    }
}

class Child : Parent
{

    public Child()
    {
        foo = "HELLO";
    }
    protected override void DoSomething()
    {
        Console.WriteLine(foo.ToLower());
    }
}

class SecondChild : Parent
{
    public SecondChild()
    {
        var c = new Child();
    }

    protected override void DoSomething()
    {
        Console.WriteLine("In second Child");
    }
}

class Program
{
    static void Main(string[] args)
    {
        SecondChild c = new SecondChild();
        Console.ReadLine();
    }
}

此输出将是:

In second Child

parent1

为什么?查看方法调用顺序:

new SecondChild()
  -> SecondChild:base()
      -> base.DoSomething() //virtual
    -> SecondChild.DoSomething()
  -> new Child()
    -> Child:base()
      -> base.DoSomething() //virtual
    -> Child.DoSomething()

Well DoSomething() 在创建 SecondChild class 的实例时被调用,但是当您创建 class Child 的实例时,它首先执行 Parent class 的构造函数,它正在调用 child class 的 DoSomething 方法,这没问题,但是因为 Child class 的构造函数尚未执行,foo 字段还没有执行 foo.ToLower() throws null引用异常。

DoSomething 在 Child class 中被调用两次,在 SecondChild 中被调用一次,但在 Child class 中抛出异常,因为 foo 为 null

所以这里的棘手部分是基础构造函数在派生的构造函数之前执行 class