在基类构造函数中构造对象?

时间:2013-04-09 09:56:28

标签: c# oop constructor

我目前有以下代码模式,我在一般类MyClass的构造函数中初始化MyThing类型的特定对象。但是,在某些特定的派生类示例(例如MySpecialClass)中,我想使用MyThing的派生版本,我称之为MySpecialThing。

public class MyClass
{
    public MyClass()
    {
        this.MyThing = new MyThing();
    }

    public MyThing MyThing { get; set; }
}

public class MySpecialClass : MyClass
{
    public MySpecialClass()
    {
        this.MyThing = new MySpecialThing();
    }
}

我的问题是这是否是不好的做法,因为实际上MyThing属性被初始化两次,一次在基类中,一次在派生类中。显然我可以将一个布尔值传递给基类构造函数或其他东西告诉它不要打扰初始化MyThing,但这可能有点过分......

3 个答案:

答案 0 :(得分:5)

这取决于创建MyThing需要多少开销。

但是,有一个解决方案:

您可以添加一个受保护的基类构造函数,该构造函数接受MyThing类型的参数,并在那里初始化它。

public class MyClass
{
    private readonly MyThing myThing;

    public MyClass(): this(new MyThing())
    {
    }

    protected MyClass(MyThing thing)
    {
        Contract.Requires(thing != null);
        myThing = thing;
    }

    public MyThing MyThing { get { return myThing; } }
}

public class MySpecialClass : MyClass
{
    public MySpecialClass(): base(new MySpecialThing())
    {
    }
}

我认为这比向公共基类构造函数添加bool更好。

即使构建MyThing的开销很小,我也认为这是值得做的,因为它更清楚地表达了设计。

我还稍微改变了设计,使myThing成为一个只读字段,以表达它只应在构造时设置的意图。 (如果情况并非如此,并且您希望以后可以设置它,则必须恢复为公共属性设置器。)

答案 1 :(得分:1)

您是否关注性能或可维护性?

只有MyThing构造函数很昂贵,或者你必须在紧密循环中创建大量对象时才会出现性能问题。

我会更担心可维护性,因为你有多个初始化对象状态的地方。您可以从派生类将其传递给受保护的基类构造函数,并且具有默认使用MyThing的默认构造函数

答案 2 :(得分:0)

使用protected:

class BaseClass
{
    protected SomeType MyThing;
}