[英]How can I have an overloaded constructor call both the default constructor as well as an overload of the base constructor?
也許我說過的問題不是正確的問題,因為我已經知道簡短的回答是“你不能”。
我有一個帶有重載構造函數的基類,它帶有兩個參數。
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 }
現在我想創建一個子類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()
我想知道我的設計是否有問題讓我想要同時調用base(地址,價格)和this()。 也許我不應該在構造函數中設置BuildingType而在其他地方? 我試圖為此引入一個字段。
public BuildingType BuildingType = BuildingType.General;
但后來我不能在子課上做同樣的事。 我將隱藏基類中的BuildingType字段,因此我必須在子類中使用new
運算符。 我已經嘗試在基類中創建BuildingType virtual
,但是不能將字段設為虛擬。
在這個簡單的示例中,默認構造函數僅為某些屬性分配默認值。 但構建構造函數也可以為構建創建一個Foundation,而Office默認構造函數可能會創建一個......(想不出什么,但是你明白了)。 那么你仍然想要執行兩個默認構造函數。
我在這里想錯了方向嗎?
根據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;
}
}
您(Jon 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
參數。)
創建一個私有方法,為所有屬性分配默認值,並分別從每個構造函數中調用它們。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.