我怎么能有一个重载的构造函数调用默认的构造函数以及基础构造函数的重载?

也许我所说的问题不是正确的问题,因为我已经知道简短的答案是“你不能”。

情况

我有一个带有两个参数的重载构造函数的基类。

class Building { public BuildingType BuildingType { get; protected set; } public string Address { get; set; } public decimal Price { get; set; } public Building() { BuildingType = BuildingType.General; Address = "Unknown"; } public Building(string address, decimal price) : this() { Address = address; Price = price; } } 

这个类正在使用一个枚举

 enum BuildingType { None, General, Office, Apartment } 

现在我想创build一个子类Office,它也有一个重载的构造函数。 这个子类添加了另一个属性(公司)。 在这个类中,BuildingType属性应该被设置为Office。 这是代码。

 class Office : Building { public string Company { get; set; } public Office() { BuildingType = BuildingType.Office; } public Office(string address, decimal price, string company) : base(address, price) { Company = company; // BuildingType = BuildingType.Office; // Don't wanna repeat statement } } 

我想要什么,为什么

我想为Office类的第二个构造函数执行base(address, price)构造函数以及Office类的默认构造函数。 我想调用base(address, price)构造函数,所以我不必重复指定基类的所有属性。 我想调用Office类的默认构造函数,因为它将BuildingType属性设置为BuildingType.Office。

现在我知道我不能使用这样的东西。

 public Office(string address, decimal price, string company) : base(address, price) this() 

难道我做错了什么?

我想知道如果我的devise有什么问题,使我想调用基地(地址,价格)和这()。 也许我不应该在构造函数中设置BuildingType,而是在别的地方? 我试图为此介绍一个领域。

  public BuildingType BuildingType = BuildingType.General; 

但是,我不能在孩子class上做同样的事情。 我会隐藏基类中的BuildingType字段,所以我不得不在子类中使用new运算符。 我已经尝试使基类virtual的BuildingType,但一个字段不能被虚拟。

在基础构造函数中创build一些东西

在这个简单的例子中,默认的构造函数只给一些属性赋予默认值。 但是build筑构造函数也可以为build筑物创build一个基础,而Office默认的构造函数可能会创build一个…(想不到什么东西,但是你明白了)。 那么你仍然想要执行两个默认的构造函数。

我在这里思考错误的方向吗?


更新

基于Jon Skeet的回答和评论,这是我的新代码。 我已经从最不具体到最具体的更改构造函数链。 我还将BuildingType添加到Building类的构造函数中,使构造函数受到保护,并使属性setter变为私有。

 enum BuildingType { None, General, Office, Apartment } class Building { private const string DefaultAddress = "Unknown"; public BuildingType BuildingType { get; private set; } public string Address { get; set; } public decimal Price { get; set; } #region Optional public constructors // Only needed if code other than subclass must // be able to create a Building instance. // But in that case, the class itself can be abstract public Building() : this(DefaultAddress, 0m) {} public Building(string address, decimal price) : this(BuildingType.General, address, price) {} #endregion protected Building(BuildingType buildingType) : this(buildingType, DefaultAddress, 0m) {} protected Building(BuildingType buildingType, string address, decimal price) { BuildingType = buildingType; Address = address; Price = price; } } class Office : Building { public string Company { get; set; } public Office() : this("Unknown Office", 0m, null) {} public Office(string address, decimal price, string company) : base(BuildingType.Office, address, price) { Company = company; } } 

你可以(乔恩Skeet或其他人)请评论这个修订版本的代码?

一个(次要的)问题不能解决的是,Office类的默认构造函数仍然需要提供一个默认的地址(在上面的代码中是"Unknown Office" )。 如果没有指定地址,我仍然希望让基类的构造函数决定地址。 所以这段代码仍然没有做到我想要的。

我可以通过在派生类中不使用构造函数链来解决这个问题,而是直接调用它的构造函数。 这将意味着我会更改Office类的默认构造函数

 public Office() : base(BuildingType.Office) 

这将适用于这个简单的例子,但如果有一些方法,我想要在Office的每个实例上执行,我必须在所有构造函数中调用。 这就是为什么构造函数链接听起来像一个更好的主意给我。

你的方法不是传统方法,可以解决问题。 而不是使更具体的构造函数(具有很多参数的构造函数)调用无参数的构造函数,反过来做 – 使无参数的构造函数调用另一个,提供默认值。 这通常会导致所有构造函数禁止每个类中的一个调用一个“主”构造函数(可能间接通过其他函数),并且“主”构造函数调用构造函数调用。

 class Office : Building { public string Company { get; set; } public Office() : this(null, 0m, null) { } public Office(string address, decimal price, string company) : base(address, price) { Company = company; BuildingType = BuildingType.Office; // Don't wanna repeat statement } } 

…在基类中是一样的:

 class Building { public BuildingType BuildingType { get; protected set; } public string Address { get; set; } public decimal Price { get; set; } public Building() : this("Unknown", 0m) { } public Building(string address, decimal price) { BuildingType = BuildingType.General; Address = address; Price = price; } } 

(我会认真考虑使Building构造函数也包含一个BuildingType参数。)

创build一个私有方法,将默认值分配给所有属性,并分别从每个构造函数中调用它们。