在基类构造函数中构造对象?
问题描述:
我目前有以下代码模式,我在一般类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,但可能是矫枉过正...
答
这取决于有多少开销有创造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
成为只读字段,以表达它应该只在施工时设置的意图。 (如果情况并非如此,并且您希望稍后设置,则必须恢复为公共财产设置工具。)
答
使用保护:
class BaseClass
{
protected SomeType MyThing;
}
答
您是否关注性能或可维护性?
性能问题只有在构造函数昂贵时才有意义,或者您必须在紧密循环中创建大量对象。
我会更担心可维护性,因为您有多个地方初始化对象状态。您可以将它传递给派生类的受保护的基类构造函数,并且默认使用MyThing
默认构造函数
您甚至可以委托基类中的默认构造函数:public MyClass():this(new MyThing() ){}',但这只是一个意见问题:)总体而言,+1。 – 2013-04-09 10:01:53
好点,我会调整代码。 – 2013-04-09 10:02:59
很好的答案,谢谢。关于使其只读的好主意。我通常是只读变量的粉丝,它只是令人讨厌,没有类似于{get;组; }表示只读属性和字段的表示法。 – 2013-04-09 10:14:02