简体   繁体   English

C#在自己的构造函数之后调用基类的构造函数?

[英]C# Call base class' constructor after own constructor?

How can I call base class' constructor after I've called my own constructor?调用自己的构造函数后,如何调用基类的构造函数?

The problem is, base class' constructor calls an abstract method (overridden in sub class), which needs to access variable x , initialized in sub class' constructor?问题是,基类的构造函数调用一个抽象方法(在子类中重写),它需要访问变量x ,在子类的构造函数中初始化?

Short example code:简短的示例代码:

abstract class BaseClass
{
    protected string my_string;

    protected abstract void DoStuff();

    public BaseClass()
    {
        this.DoStuff();
    }
}

class SubClass : BaseClass
{
    private TextBox tb;

    public SubClass()
        : base()
    {
        this.my_string = "Short sentence.";
    }

    protected override void DoStuff()
    {
        // This gets called from base class' constructor
        // before sub class' constructor inits my_string
        tb.Text = this.my_string;
    }
}

Edit: Based on answers, it obviously is not possible.编辑:根据答案,这显然是不可能的。 Is there an automated way to call this.DoStuff();是否有自动调用this.DoStuff(); on every object of SubClass once they're created?一旦创建了SubClass每个对象? Of course I could just add this.DoStuff();当然我可以添加this.DoStuff(); after all the other lines in sub class' constructor, but having around 100 of these classes, it feels stupid.在子类的构造函数中的所有其他行之后,但是有大约 100 个这样的类,感觉很愚蠢。 Any other solution, or should I use the manual one?任何其他解决方案,还是我应该使用手动解决方案?

You can't.你不能。

Also, you generally shouldn't call virtual methods in a constructor.此外,您通常不应在构造函数中调用virtual方法。 See this answer .看到这个答案


Depending on your actual code and not the simple example you wrote, you could pass values as parameters of the base constructor and the DoStuff method.根据您的实际代码而不是您编写的简单示例,您可以将值作为基本构造函数和DoStuff方法的参数传递。 For example:例如:

abstract class BaseClass
{
    private string my_string;

    protected abstract void DoStuff(string myString);

    public BaseClass(string myString)
    {
        this.my_string = myString;
        this.DoStuff(this.my_string);
    }
}

class SubClass : BaseClass
{
    private TextBox tb;

    public SubClass()
        : base("Short sentence.")
    {
    }

    protected override void DoStuff(string myString)
    {
        tb.Text = myString;
    }
}

If it's not possible with your actual code, then writing multiple DoStuff() will do the job.如果您的实际代码无法实现,那么编写多个DoStuff()就可以完成这项工作。 Also remember to seal your SubClass class so nobody else will be able to introduce bugs by modifying the DoStuff method another time.还要记住密封您的SubClass类,这样其他人就无法再次通过修改DoStuff方法来引入错误。

I would not call an abstract method in the constructor as it can happen that the constructor for the instance that invokes the method has not executed我不会在构造函数中调用抽象方法,因为调用该方法的实例的构造函数可能没有执行

When a virtual method is called, the actual type that executes the method is not selected until run time.当调用虚拟方法时,直到运行时才选择执行该方法的实际类型。 When a constructor calls a virtual method, it is possible that the constructor for the instance that invokes the method has not executed.当构造函数调用虚方法时,调用该方法的实例的构造函数可能尚未执行。 To fix a violation of this rule, do not call a type's virtual methods from within the type's constructors.要修复违反此规则的情况,请不要从类型的构造函数中调用类型的虚拟方法。

http://msdn.microsoft.com/en-us/library/ms182331%28v=vs.80%29.aspx http://msdn.microsoft.com/en-us/library/ms182331%28v=vs.80%29.aspx

You can't do it like that.你不能那样做。 But you can put your initiation code of the master class into a separate initialize method.但是您可以将主类的启动代码放入单独的 initialize 方法中。 You then can call that method in your specific constructor >after the constructor code.然后,您可以在特定的构造函数中 > 在构造函数代码之后调用该方法。

Is there a reason you can't construct a class before its constructor actually runs?有没有理由在类的构造函数实际运行之前不能构造它? It requires a greater level of responsibility on how the derived class is created and probably not a best practice, but it appears to work.它需要对如何创建派生类承担更大的责任,这可能不是最佳实践,但它似乎有效。

abstract class BaseClass {
    protected string my_string;

    protected abstract void DoStuff();

    public BaseClass() {
        this.DoStuff();
    }
}

class SubClass: BaseClass {
    TextBox tb;

    bool Constructed = false;
    void Constructor() {
        if (!Constructed) {
            Constructed = true;
            this.my_string = "Short sentence.";
        }
    }
    public SubClass()
        : base() {
        Constructor();
    }

    protected override void DoStuff() {
        Constructor();
        // This gets called from base class' constructor
        // before sub class' constructor inits my_string
        tb.Text = this.my_string;
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM