【问题标题】:Reversed order of constructor calls by inheriting a constructor通过继承构造函数来反转构造函数调用的顺序
【发布时间】:2009-08-26 11:00:01
【问题描述】:

我有一个类,它首先需要在调用基构造函数之前调用派生类构造函数。我知道通过以下代码将首先调用基本构造函数:

public class A {

    protected A () {
        //do something
    }

}

public class B : A {

    public B () : base() {
        //do something else
    }

}

他们是一种反转该顺序的方法,还是一种解决方法?一种可能的解决方案是,我们在基类中创建一个额外的受保护方法,如 doConstructor(),并在第一个任务之后在派生的构造函数中调用它,这对于只读字段是不可能的,因为编译器不会接受它。

【问题讨论】:

    标签: c# inheritance constructor


    【解决方案1】:

    没有直接的方法可以做到这一点。过去我也遇到过这种情况,使用Initialize方法解决。

    public class A
    {
        protected A()
        {
            // Do pre-initialization here still.
    
            Initialize();
        }
    
        protected virtual Initialize()
        {
            // Do all post-derived-class initialization here.
        }
    }
    
    public class B : A
    {
        public B()
            : base()
        {
        }
    
        protected override Initialize()
        {
            // Do initialization between pre- and post- initialization here.
    
            base.Initialize();
        }
    }
    

    只要您遵循此处的预初始化、后初始化和正常初始化的准则,它可能是相当安全且符合良好实践的。

    【讨论】:

    • 看起来你正在阅读我屏幕上的代码;o) 我们应该知道,尽管通常建议不要从构造函数调用虚拟成员。
    • 在基础构造函数(A)中调用虚方法有点危险; B 的覆盖现在正在运行 before B 的构造函数,这可能会导致未初始化的字段出现问题。我通常会在这里建议谨慎,或者更好:post-ctor Initialize step。
    • @Fredrik:呵呵,是的。我并不感到惊讶,这也是其他人使用的方法。我不知道不建议从构造函数中调用虚拟成员-特别是什么原因?无论如何,我认为在这种情况下它是相当安全的。
    • @Marc:好点。我将稍微澄清一下代码以说明这个问题是如何发生的(至少部分删除)。
    • @Fredrik...这通常被认为是一个坏主意,因为它总是会调用派生方法...换句话说,从基类派生会改变基类本身的执行...在这种情况下,这没关系,但一般来说,像这样更改单独类的行为可能会破坏任何依赖旧行为的依赖代码。
    猜你喜欢
    • 2011-11-24
    • 2013-01-29
    • 2016-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-11
    相关资源
    最近更新 更多