7

我有几个从简化派生的类型,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)
    {
    }
}

[编辑] 看起来伊恩·奎格利在他的回答中所建议的似乎是有道理的。如果我要进行初始化验证器的调用,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() {}
}
4

6 回答 6

5

This. Because if you ever place code in ConcreteB(string, int?) then you want the string only constructor to call it.

于 2009-04-15T13:03:21.547 回答
2

In general, I'd call "this" rather than "base". You'll probably reuse more code that way, if you expand your classes later on.

于 2009-04-15T13:03:54.480 回答
2

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

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

于 2009-04-15T13:03:56.960 回答
1

In your case from what you have provided it doesn't matter. You really only want to use this when you have a constructor in your current class that is not part of your base class, or if there is some code in the current class constructor that you want to execute that isn't contained in the base class.

于 2009-04-15T13:03:18.960 回答
0

为了降低代码路径的复杂度,我通常会尽量只base()调用一个构造函数(ConcreteB案例)。这样你就知道基类的初始化总是以同样的方式发生。

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

于 2009-04-15T13:03:54.900 回答
0

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

protected Base()

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

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

于 2009-04-15T13:23:55.167 回答