C# 在基类构造函数中构造对象?
我目前有以下代码模式,我正在初始化一般类MyClass的构造函数中MyThing类型的特定对象。然而,在一些特定的派生类示例中(例如MySpecialClass),我想使用MyThing的派生版本,我称之为MySpecialThingC# 在基类构造函数中构造对象?,c#,oop,constructor,C#,Oop,Constructor,我目前有以下代码模式,我正在初始化一般类MyClass的构造函数中MyThing类型的特定对象。然而,在一些特定的派生类示例中(例如MySpecialClass),我想使用MyThing的派生版本,我称之为MySpecialThing public class MyClass { public MyClass() { this.MyThing = new MyThing(); } public MyThing MyThing { get; set
public class MyClass
{
public MyClass()
{
this.MyThing = new MyThing();
}
public MyThing MyThing { get; set; }
}
public class MySpecialClass : MyClass
{
public MySpecialClass()
{
this.MyThing = new MySpecialThing();
}
}
我的问题是,这是否是一种不好的做法,因为实际上神话属性被初始化了两次,一次在基类中,一次在派生类中。显然,我可以将布尔值传递给基类构造函数或其他东西,告诉它不要费心初始化神话,但这可能太过分了…使用受保护的:
class BaseClass
{
protected SomeType MyThing;
}
使用受保护的:
class BaseClass
{
protected SomeType 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类型的参数,并在那里初始化它
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
成为一个只读字段,以表达只应在构建时设置的意图。(如果情况并非如此,并且您希望以后可以对其进行设置,则必须恢复到公共属性设置程序。)您关心的是性能还是可维护性
只有当虚构构造函数的成本很高,或者必须在紧循环中创建大量对象时,性能问题才有意义
我更担心可维护性,因为您有多个初始化对象状态的地方。您可以将其从派生类传递给受保护的基类构造函数,并拥有默认使用虚构的默认构造函数
您关心的是性能还是可维护性
只有当虚构构造函数的成本很高,或者必须在紧循环中创建大量对象时,性能问题才有意义
我更担心可维护性,因为您有多个初始化对象状态的地方。您可以将其从派生类传递给受保护的基类构造函数,并拥有默认使用虚构
的默认构造函数您甚至可以在基类中委托默认构造函数:public MyClass():this(new MyThing()){}
,但这只是一个意见问题:)总体而言,+1.回答很好,谢谢。让它成为只读的好主意。我通常是只读变量的爱好者,只是令人恼火的是,没有类似于{get;set;}符号的速记法来表示只读属性和字段。几年前,我确实向Microsoft Connect添加了一个“只读”属性的请求,但事实证明,由于存在一些语法和其他问题,实现起来不如我预期的那么简单。:)是的,我想目前唯一的获取值的方法是通过构造函数,很难定义“隐式”语法。他们可以改为允许在只读变量的构造函数上使用对象初始化器语法,不知道这是否会打开其他蠕虫。您甚至可以在基类中委托默认构造函数:public MyClass():this(new MyThing()){}
,但这只是一个意见问题:)总体而言,+1。回答很好,谢谢。让它成为只读的好主意。我通常是只读变量的爱好者,只是令人恼火的是,没有类似于{get;set;}符号的速记法来表示只读属性和字段。几年前,我确实向Microsoft Connect添加了一个“只读”属性的请求,但事实证明,由于存在一些语法和其他问题,实现起来不如我预期的那么简单。:)是的,我想目前唯一的获取值的方法是通过构造函数,很难定义“隐式”语法。他们可以允许在只读变量的构造函数上使用对象初始化器语法,但不知道这是否会打开其他蠕虫。