C# 超载“;“基础”;建造商或;这";建造师?

C# 超载“;“基础”;建造商或;这";建造师?,c#,.net,overloading,constructor-overloading,C#,.net,Overloading,Constructor Overloading,我有几个从简化的Base派生的类型,如下所示 我不确定在重载构造函数时是使用基类的构造函数还是this构造函数 ConcreteA仅使用base构造函数重载构造函数,而 concrete b对前两个重载使用this重载 重载构造函数的更好方法是什么 public abstract class Base { public string Name { get; set; } public int? Age { get; set; } protected Base() : t

我有几个从简化的
Base
派生的类型,如下所示

我不确定在重载构造函数时是使用基类的构造函数还是
this
构造函数

ConcreteA
仅使用
base
构造函数重载构造函数,而
concrete b
对前两个重载使用
this
重载

重载构造函数的更好方法是什么

public abstract class Base
{
    public string Name { get; set; }
    public int? Age { get; set; }

    protected Base() : this(string.Empty) {}
    protected Base(string name) : this(name, null) {}
    protected Base(string name, int? age)
    {
        Name = name;
        Age = age;
    }
}

public class ConcreteA : Base
{
    public ConcreteA(){}
    public ConcreteA(string name) : base(name) {}
    public ConcreteA(string name, int? age) : base(name, age)
    {
    }
}

public class ConcreteB : Base
{
    public ConcreteB() : this(string.Empty, null){}
    public ConcreteB(string name): this(name, null){}
    public ConcreteB(string name, int? age) : base(name, age)
    {
    }
}
[编辑] 看起来伊恩·奎格利(Ian Quigley)在书中的建议似乎是有道理的。 如果我有一个初始化验证器的调用,
ConcreteA(string)
在下面的例子中将永远不会初始化验证器

public class ConcreteA : Base
{
    public ConcreteA(){}
    public ConcreteA(string name) : base(name) {}
    public ConcreteA(string name, int? age) : base(name, age)
    {
        InitializeValidators();
    }
    private void InitializeValidators() {}
}

在你的情况下,从你提供的情况来看,这并不重要。如果当前类中有一个构造函数不是基类的一部分,或者当前类构造函数中有一些代码不包含在基类中,您确实只想使用

。因为如果您将代码放入ConcreteB(string,int?)中,那么您希望仅字符串的构造函数调用它。

一般来说,我会调用“this”而不是“base”。如果以后扩展类,您可能会以这种方式重用更多的代码。

为了降低代码路径的复杂性,我通常尝试只调用一个
base()
构造函数(concrete b
案例)。这样您就知道基类的初始化总是以相同的方式进行的


但是,根据覆盖的类的不同,这可能不可能实现或增加不必要的复杂性。这适用于特殊的构造函数模式,例如在实现时的构造函数模式。

混合和匹配是很好的;最终,当您使用
this(…)
构造函数时,它最终将到达一个首先调用
base(…)
的构造函数。在需要时重用逻辑是有意义的


您可以安排它,以便所有构造函数调用一个公共(可能是私有)的
此(…)
构造函数,它是唯一调用
基(…)
-但这取决于a:这样做是否有用,b:是否有单个
基(…)
ctor,这将允许您使用。

再次扪心自问,为什么要在基类中重载构造函数?这个就够了:

protected Base()
子类也是如此,除非您在实例化时需要其中一个字段具有特定的值,而在您的示例中,情况并非如此,因为您已经拥有默认构造函数


还要记住,任何构造函数都应该将对象的实例置于正确的状态。

如果在具体构造函数中进行其他初始化,这似乎是有意义的。是的,“This”在一天结束时总是调用“base”。所以即使“this”不起作用,它也会降到“base”