重载“base”构造函数或“this”构造函数?

时间:2009-04-15 12:59:38

标签: c# .net overloading constructor-overloading

我的简化Base衍生的类型很少,如下所示。

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

ConcreteA重载构造函数纯粹使用base构造函数,而
ConcreteB使用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在answer中提出的建议似乎有道理。 如果我要进行初始化验证器的调用,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() {}
}

6 个答案:

答案 0 :(得分:5)

:此即可。因为如果你在ConcreteB中放置代码(string,int?),那么你希望字符串只有构造函数来调用它。

答案 1 :(得分:2)

一般来说,我称之为“这个”而不是“基础”。如果稍后扩展您的类,您可能会以这种方式重用更多代码。

答案 2 :(得分:2)

混合搭配很好;最终,当你使用this(...)构造函数时,它最终会到达首先调用base(...)的ctor。在需要时重新使用逻辑是有意义的。

你可以安排它,以便所有构造函数调用一个公共(可能是私有的)this(...)构造函数,它是唯一一个调用base(...)的构造函数 - 但这取决于是否:它是这样做很有用,b:是否有一个base(...) ctor可以让你。

答案 3 :(得分:1)

根据您提供的内容,无关紧要。当你的当前类中的构造函数不是你的基类的一部分,或者你想要执行的当前类构造函数中有一些未包含的代码时,你真的只想使用this在基类。

答案 4 :(得分:0)

为了降低代码路径的复杂性,我通常会尝试只有一个base()构造函数调用(ConcreteB情况)。这样您就知道基类的初始化总是以相同的方式发生。

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

答案 5 :(得分:0)

再问自己为什么要在Base类中重载构造函数?这个就足够了:

protected Base()

对于子类也是如此,除非您在实例化时需要任何一个字段具有特定值,因为您已经拥有默认构造函数,因此在您的示例中不是这样。

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