C# 调用派生类的构造函数在基类的构造函数之前执行

C# 调用派生类的构造函数在基类的构造函数之前执行,c#,inheritance,constructor,C#,Inheritance,Constructor,最初,我在每个派生类中都有两个不同值的常量(比如MAX_SPEED)。其想法是在基类的某些方法中使用这些值。那时候我意识到我不能用常量来实现,所以我创建了只读属性 我需要一个方法在实例化时将这些值分配给私有字段,最好是在基类中。但首先我必须在派生类中分配原始值。由于这些都是属性,我在定义时找不到初始化它们的方法,所以唯一的方法是在派生构造函数中进行初始化 问题就出在这里:值在分配给基类中的私有字段后被初始化。我得到的解决方案是创建一个虚拟方法,并在那里进行赋值 有没有一种方法可以从派生类中调用基

最初,我在每个派生类中都有两个不同值的常量(比如MAX_SPEED)。其想法是在基类的某些方法中使用这些值。那时候我意识到我不能用常量来实现,所以我创建了只读属性


我需要一个方法在实例化时将这些值分配给私有字段,最好是在基类中。但首先我必须在派生类中分配原始值。由于这些都是属性,我在定义时找不到初始化它们的方法,所以唯一的方法是在派生构造函数中进行初始化


问题就出在这里:值在分配给基类中的私有字段后被初始化。我得到的解决方案是创建一个虚拟方法,并在那里进行赋值

有没有一种方法可以从派生类中调用基构造函数,以便首先调用派生构造函数中的代码

class BaseClass
{
    public BaseClass()
    {
        System.Console.WriteLine("This should be shown after");
    }
}

class DerivedClass : BaseClass
{
    public DerivedClass() : base()
    {
        System.Console.WriteLine("This should be shown first");
    }
}

当然,在这个例子中,它会反过来工作。是否有解决方案?

否。基类构造函数总是在派生类构造函数的主体之前执行。然而:

  • 派生类中的任何实例变量初始值设定项都在基类构造函数之前执行
  • 基类构造函数可以执行可以在派生类中重写的虚拟方法但这几乎总是一个坏主意。(此时所有类型的正常前提条件都无效。您可以观察尚未设置的只读变量,因为它们将在构造函数体中设置,例如.Ick。)
要演示这两个方面,请执行以下操作:

using System;

class BaseClass
{
    public BaseClass()
    {
        VirtualMethod();
        Console.WriteLine("BaseClass ctor body");
    }

    public virtual void VirtualMethod()
    {
        Console.WriteLine("BaseClass.VirtualMethod");
    }
}

class DerivedClass : BaseClass
{
    int ignored = ExecuteSomeCode();

    public DerivedClass() : base()
    {
        Console.WriteLine("DerivedClass ctor body");
    }

    static int ExecuteSomeCode()
    {
        Console.WriteLine("Method called from initializer");
        return 5;
    }

    public override void VirtualMethod()
    {
        Console.WriteLine("DerivedClass.VirtualMethod");
    }
}

class Test
{
    static void Main()
    {
        new DerivedClass();
    }
}
输出:

Method called from initializer
DerivedClass.VirtualMethod
BaseClass ctor body
DerivedClass ctor body
此外,如果基类构造函数接受参数,则可以在派生类中执行一些代码以提供参数:

DerivedClass() : base(SomeStaticMethod())

但所有这些都相当难闻。你的具体情况是什么?

不,你不能那样做。基类总是先初始化。但是,您可以这样做:

class BaseClass
{
    public BaseClass()
    {
        this.Initialize();
    }

    protected virtual void Initialize()
    {
        System.Console.WriteLine("This should be shown after");
    }
}

class DerivedClass : BaseClass
{
    public DerivedClass() : base()
    {
    }

    protected override void Initialize()
    {
        System.Console.WriteLine("This should be shown first");
        base.Initialize();
    }
}

还有一个选项是使子类构造函数成为静态的,以便它比父类构造函数先执行。但它不符合oop设计

否。您必须首先调用基本构造函数,如果不这样做,您将得到一个错误。顺便说一句,你为什么想要这个?我在对乔恩回答的评论中描述了这种情况。我想我应该在问题中说清楚。这正是我在与构造函数失败后在真实程序中所做的!无论如何谢谢你!最初,我在每个派生类中都有两个不同值的常量(比如MAX_SPEED)。其想法是在基类的某些方法中使用这些值。这时我意识到我不能用常量来实现这一点,所以我创建了只读属性。我需要一个方法在实例化时将这些值分配给私有字段,最好是在基类中。但首先我必须在派生类中分配原始值。由于这些都是属性,我在定义时找不到初始化它们的方法,所以唯一的方法是在派生构造函数中进行初始化。这就是问题所在:在将值赋给基类中的私有字段后,会初始化这些值。我得到的解决方案是(正如您所提到的)创建一个虚拟方法并在那里赋值。@msgmaxim:您能用派生类中的静态方法计算最大值,并将其作为参数传递给基类吗?我强烈建议不要使用构造函数中的虚拟方法,除非真的没有其他方法。它可能会变得非常复杂。我想这也可能是解决方案。