gpt4 book ai didi

c# - 如何让重载的构造函数同时调用默认构造函数和基构造函数的重载?

转载 作者:IT王子 更新时间:2023-10-29 03:52:38 28 4
gpt4 key购买 nike

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

情况

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

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(address, price) 和 this()。也许我不应该在构造函数中设置 BuildingType 而应该在其他地方设置?我试图为此引入一个字段。

    public BuildingType BuildingType = BuildingType.General;

但是我不能在子类中做同样的事情。我将隐藏基类中的 BuildingType 字段,因此我必须在子类中使用 new 运算符。我已尝试将基类中的 BuildingType 设为 virtual,但无法将字段设为 virtual。

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

在这个简单的示例中,默认构造函数只为某些属性分配默认值。但是 Building 构造函数也可能正在为建筑物创建 Foundation,而 Office 默认构造函数可能会创建一个......(想不出来,但你明白了)。所以你仍然想执行两个默认构造函数。

我是不是想错方向了?


更新

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

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 参数。)

关于c# - 如何让重载的构造函数同时调用默认构造函数和基构造函数的重载?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4412875/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com