过载“基础” 构造函数或“this” 构造函数?

发布于 2024-07-17 06:53:14 字数 1515 浏览 10 评论 0原文

我有一些从简化的 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() {}
}

I have few types that derive from simplified Base as shown below.

I am not sure whether to use base class's constructor or this constructor when overloading constructors.

ConcreteA overloads constructors purely using base constructors, while
ConcreteB overloads using this for the first two overloads.

What would be a better way of overloading constructors?

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)
    {
    }
}

[Edit]
It looks like what Ian Quigley has suggested in his answer seemed to make sense.
If I were to have a call that initialize validators, ConcreteA(string) will never initialize validators in following case.

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() {}
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

鱼忆七猫命九 2024-07-24 06:53:15

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

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

久伴你 2024-07-24 06:53:15

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

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

祁梦 2024-07-24 06:53:15

混搭就好; 最终,当您使用 this(...) 构造函数时,它将最终到达调用 base(...) 的 ctor第一的。 在需要时重用逻辑是有意义的。

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

It is fine to mix and match; ultimately, when you use a this(...) constructor, it will eventually get to a ctor that calls base(...) first. It makes sense to re-use logic where required.

You could arrange it so that all the constructors called a common (maybe private) this(...) constructor that is the only one that calls down to the base(...) - but that depends on whether a: it is useful to do so, and b: whether there is a single base(...) ctor that would let you.

感情洁癖 2024-07-24 06:53:15

就您的情况而言,从您提供的内容来看,这并不重要。 当当前类中有一个不属于基类的构造函数,或者当前类构造函数中有一些您想要执行的代码时,您实际上只想使用 this不包含在基类中。

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.

要走就滚别墨迹 2024-07-24 06:53:15

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

但是,根据您覆盖的类,这可能是不可能的,或者会增加不必要的复杂性。 这对于特殊的构造函数模式来说是正确的,例如实现 可序列化

In order to reduce the complexity of the code paths, I usually try to have exactly one base() constructor call (the ConcreteB case). This way you know that the initialization of the base class always happens in the same fashion.

However, depending on the class you override, this may not be possible or add unneeded complexity. This holds true for special constructor patterns such as the one when implementing ISerializable.

尹雨沫 2024-07-24 06:53:15

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

protected Base()

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

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

Ask yourself again why you are overloading the constructor in the Base class? This one is enough:

protected Base()

Same goes for the subclass unless you need either fields to have a particular value when you instantiate which in your example is not the case since you already have the default constructor.

Also remember that any constructor should put the instance of the object in a correct state.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文