从子类提供抽象类成员变量

发布于 2024-08-10 04:56:15 字数 607 浏览 4 评论 0原文

从具体子类在抽象类中提供值的“正确”方法是什么?

即,我应该这样做:

abstract class A {
    private string m_Value;

    protected A(string value) {
        m_Value = value;
    }

    public string Value {
        get { return m_Value; }
    }
}

class B : A {
    B() : this("string value") {}
}

或这个:

abstract class A {

    protected A() { }

    public abstract string Value { get; }
}

class B : A {
    B() {}

    public override string Value {
        get { return "string value"; }
    }
}

或其他什么?

如果 Value 属性仅在抽象类中使用,是否应该做不同的事情?

What is the 'correct' way of providing a value in an abstract class from a concrete subclass?

ie, should I do this:

abstract class A {
    private string m_Value;

    protected A(string value) {
        m_Value = value;
    }

    public string Value {
        get { return m_Value; }
    }
}

class B : A {
    B() : this("string value") {}
}

or this:

abstract class A {

    protected A() { }

    public abstract string Value { get; }
}

class B : A {
    B() {}

    public override string Value {
        get { return "string value"; }
    }
}

or something else?

And should different things be done if the Value property is only used in the abstract class?

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

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

发布评论

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

评论(7

我不在是我 2024-08-17 04:56:15

我通常更喜欢第一种方法,因为它在子类中需要更少的代码。

然而,我承认第二种方法的语义在某种程度上更清晰。覆盖该属性表示“此属性的实现是我的身份的一部分。”传递构造函数参数具有不同的含义:“我正在另一个东西中设置一个值,它恰好是我的基类。”它意味着组合(has-a)而不是继承(is-a)。

如果出现以下情况,应该采取不同的措施吗?
Value 属性仅用于
抽象类?

在这种情况下,您绝对应该使用第一种(面向构造函数)方法,这样您就可以从子类中隐藏该实现细节。

同样,如果您需要在构造函数中使用该值;正如 Marc 提到这是一个实际的技术使用第一种方法的原因。尽管在这种特定情况下这并不重要,但如果有人稍后修改属性重写以使用派生类中的某些其他成员变量,您可能会遇到一个微妙的错误。

I usually prefer the first approach because it requires less code in child classes.

However, I admit that the semantics of the second approach are clearer in a subtle way. Overriding the property says "this property's implementation is part of my identity." Passing a constructor argument has a different connotation: "I'm setting a value in this other thing, which just happens to be my base class." It implies composition (has-a) rather than inheritance (is-a).

And should different things be done if
the Value property is only used in the
abstract class?

In this case, you should definitely use the first (constructor-oriented) approach so you can hide that implementation detail from subclasses.

Likewise if you need to use the value in the constructor; as Marc mentioned this is an actual technical reason to use the first approach. Though it wouldn't matter in this specific scenario, if someone later modifies the property override to use some other member variable in the derived class, you might have a subtle bug on your hands.

清醇 2024-08-17 04:56:15

这取决于;基类需要在 ctor 中了解它吗?如果是这样,override方法可能是一个坏主意(virtual在ctor内部不能很好地工作)。否则,两者都可以。

It depends; does the base-class need to know about it in the ctor? If so, the override approach may be a bad idea (virtual doesn't work very well inside the ctor). Otherwise, either is OK.

固执像三岁 2024-08-17 04:56:15

我认为第二个习惯用法更好,因为它更易于管理(如果您的基类需要在派生类中定义多个属性,则构造函数可能会变得混乱)。信息的来源也更加清晰。如果您看到 Value 属性,您就知道它是在子类中定义的。在第一个示例中,您必须跟踪 m_Value 变量的定义点,该变量可以在基类中进行修改。

I think the second idiom is better, as it is more manageable (if your base class needs multiple properties defined in a derived class, the constructor can get messy). It is also clearer where the information comes. If you see the Value property you know that it is defined in a subclass. In the first example, you have to track the definition point of the m_Value variable, which could be modified in the base class.

两相知 2024-08-17 04:56:15

我认为这几乎是一样的,选择一种方式并坚持使用以保持连贯性。

您的两个解决方案都强制派生类提供一个值,这很好;一个可能的替代方案,以防不需要值:

abstract class A {
    public string Value {
        get;
        protected set;
    }
}

我个人的偏好是您的第一个选择(构造函数参数),因为我个人认为这是更清晰的选择,但这实际上是一个品味问题。

I think it's pretty much the same, choose one way and stick to that for coherence.

Both your solutions are forcing the derived class to provide a value, which is good; a possible alternative, in case a value should not be required:

abstract class A {
    public string Value {
        get;
        protected set;
    }
}

My personal preference is your first option (constructor parameter), because I personally think that it's the clearer one, but it's really a matter of taste.

横笛休吹塞上声 2024-08-17 04:56:15

这取决于。

如果我需要修改抽象类中的Value,我将使用第一种方法。

仅当我需要从 A 继承许多类并且在某处需要将继承的类装箱到基本抽象类时,我才会使用第二种方法。

如果上述两种情况都不成立,我将使用第二种更易于管理和干净的方法。

如果 Value 仅在抽象类中使用,我会将其声明为 private 字段而不是属性。

It depends.

I will use the first way if I need to modify Valuein abstract class.

I will use the second way only if I need to inherit many classes from A and somewhere, I need to box the inherited classes to the base abstract class.

If both of the above are not true, I will use the second approach which is more manageable and clean.

If Value is only used in abstract class, I will declare it as a private field instead of a property.

瀟灑尐姊 2024-08-17 04:56:15

第二种情况的一个主要优点是它允许子类定义可能比简单标量值更复杂的 Value 属性的行为。例如,您可能希望根据子类定义的其他字段来计算值。对于第一种方法,这是不可能的,但第二种方法允许这样做。

One major advantage of the second case is that it allows a subclass to define behaviour for the Value property that may be more complex than a simple scalar value. For example, you might want to compute the Value based on other fields that the subclass defines. With the first approach, that is an impossibility, but the second approach allows for that.

青萝楚歌 2024-08-17 04:56:15

我更喜欢第二个。如果该值是常量或可以在运行时计算,它允许您提供一个值,而无需向类添加实际字段。您拥有的状态越少(字段越少),您可能会发现代码越易于维护。

I prefer the second. It lets you provide a value without adding an actual field to the class if the value is constant or can be calculated at runtime. The less state you have (fewer fields) the more maintainable you'll likely find the code to be.

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