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

Posted

技术标签:

【中文标题】C#在自己的构造函数之后调用基类的构造函数?【英文标题】:C# Call base class' constructor after own constructor? 【发布时间】:2013-01-11 20:03:01 【问题描述】:

我如何调用基类的构造函数我已经调用了自己的构造函数?

问题是,基类的构造函数调用了一个抽象方法(子类重写),需要访问变量x,在子类的构造函数中初始化?

简短的示例代码:

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;
    

编辑:根据答案,这显然是不可能的。创建 SubClass 的每个对象后,是否有自动调用 this.DoStuff(); 的方法?当然,我可以在子类的构造函数中的所有其他行之后添加this.DoStuff();,但是拥有大约 100 个这样的类,感觉很愚蠢。还有其他解决方案,还是我应该使用手动解决方案?

【问题讨论】:

实际上我不认为你可以,至少不能以一种标准的方式(使用反射也许你可以,但我认为这不是一个好方法) 你不能。想想看 - 你的班级依赖于它的父班级。如何在不先创建父级的情况下创建类的实例? 查看我的编辑。我想我只是在每个子类的构造函数中手动添加一行,没什么大不了的。仍然值得问:-) 【参考方案1】:

你不能那样做。但是您可以将主类的启动代码放入单独的初始化方法中。然后,您可以在特定构造函数中调用该方法 > 在构造函数代码之后。

【讨论】:

【参考方案2】:

在构造函数实际运行之前你不能构造一个类有什么原因吗?它需要对如何创建派生类承担更大的责任,这可能不是最佳实践,但它似乎有效。

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;
    

【讨论】:

【参考方案3】:

你不能。

此外,您通常不应在构造函数中调用virtual 方法。看到这个answer。


根据您的实际代码而不是您编写的简单示例,您可以将值作为基本构造函数和DoStuff 方法的参数传递。例如:

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;
    

如果您的实际代码无法实现,那么编写多个DoStuff() 即可。还要记住密封你的 SubClass 类,这样其他人就不能再通过修改 DoStuff 方法来引入错误了。

【讨论】:

【参考方案4】:

我不会在构造函数中调用抽象方法,因为调用该方法的实例的构造函数可能没有执行

调用虚拟方法时,直到运行时才会选择执行该方法的实际类型。当构造函数调用虚方法时,调用该方法的实例的构造函数可能尚未执行。 要修复违反此规则的行为,请不要从类型的构造函数中调用类型的虚方法。

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

【讨论】:

以上是关于C#在自己的构造函数之后调用基类的构造函数?的主要内容,如果未能解决你的问题,请参考以下文章

C++中的派生类,可以不定义对象直接调用基类的成员和调用自己的成员函数嘛???

生成一个派生类对象时,调用基类和派生类构造函数按啥次序

C++中派生类的构造函数怎么显式调用基类构造函数?

C++中如何在子类的构造函数中调用基类的构造函数来初始化基类成员变量

c#学习-base和this在构造函数中的应用

派生类的构造函数