C# 初始化基类与派生类中的基类属性

C# 初始化基类与派生类中的基类属性,c#,inheritance,architecture,C#,Inheritance,Architecture,假设我们在应用程序中有几个操作。因此,我们创建了一个AbstractAction,例如ActionMove,它将继承AbstractAction 现在,我和我的同事发生了争执。他认为actionType应该在ActionMove构造函数中分配: public ActionMove(Unit owner, Vector3 destination) : base(owner) { actionType = ActionType.Move; /**/ } public Abstrac

假设我们在应用程序中有几个操作。因此,我们创建了一个AbstractAction,例如ActionMove,它将继承AbstractAction

现在,我和我的同事发生了争执。他认为actionType应该在ActionMove构造函数中分配:

public ActionMove(Unit owner, Vector3 destination) : base(owner)
{
    actionType = ActionType.Move;
    /**/
}
public AbstractAction(ActionType actionType, Unit owner)
{
    this.actionType = actionType;
    this.owner = owner;
}

public ActionMove(Unit owner, Vector3 destination) : base(ActionType.Move, owner)
{
    /**/
}
我认为AbstractAction构造函数应该设置派生类构造函数提供的操作类型:

public ActionMove(Unit owner, Vector3 destination) : base(owner)
{
    actionType = ActionType.Move;
    /**/
}
public AbstractAction(ActionType actionType, Unit owner)
{
    this.actionType = actionType;
    this.owner = owner;
}

public ActionMove(Unit owner, Vector3 destination) : base(ActionType.Move, owner)
{
    /**/
}

他说我的变种不好,尽管他说不出原因。我不能说它很好,我只是觉得它很适合我。那么,你能告诉我哪条路更好,为什么?或者可能有第三种方法?

如果所有操作都有actionType,那么它应该在基类中。没有太大的区别,但我也会研究可读性和简单性。顺便说一句,我不会有两节课,只有一节课。如果actionType只特定于ActionMove,那么actionType应该在ActionMove中。

如果所有操作都有actionType,那么它应该在基类中。没有太大的区别,但我也会研究可读性和简单性。顺便说一句,我不会有两节课,只有一节课。如果actionType只针对ActionMove,那么actionType应该在ActionMove中。

我同意你的看法。由于ActionType是从AbstractAction继承的所有类的公共属性,因此应该在AbstractAction构造函数中设置它。

我同意你的看法。由于ActionType是从AbstractAction继承的所有类的公共属性,因此应该在AbstractAction构造函数中设置它。

我同意其他回答者的观点,如果ActionType是所有操作的公共属性,那么应该在基类中指定它。在我看来,这似乎是一个分离关注点的简单问题:如果基类定义了属性,那么最好的做法就是让基类处理它。除非有特殊原因要求您从派生类设置该属性,否则我甚至建议将其setter设置为私有

请注意,通过要求在基类构造函数中提供操作类型,可以避免在创建新派生类时可能忘记设置类型。然后,基本构造函数将强制您提供它并为您设置它

另一种解决方案可能是定义一个抽象属性,然后在派生类中实现它

abstract class AbstractAction
{
    public abstract ActionType actionType { get; }
}

class ActionMove : AbstractAction
{
    public override ActionType actionType
    {
        get { return ActionType.Move; }
    }
}

此解决方案还确保所有派生类都实现该属性,因为当您不实现抽象属性时,将收到编译器警告。

我同意其他回答者的观点,即如果ActionType是所有操作的公共属性,则应在基类中指定它。在我看来,这似乎是一个分离关注点的简单问题:如果基类定义了属性,那么最好的做法就是让基类处理它。除非有特殊原因要求您从派生类设置该属性,否则我甚至建议将其setter设置为私有

请注意,通过要求在基类构造函数中提供操作类型,可以避免在创建新派生类时可能忘记设置类型。然后,基本构造函数将强制您提供它并为您设置它

另一种解决方案可能是定义一个抽象属性,然后在派生类中实现它

abstract class AbstractAction
{
    public abstract ActionType actionType { get; }
}

class ActionMove : AbstractAction
{
    public override ActionType actionType
    {
        get { return ActionType.Move; }
    }
}

此解决方案还确保所有派生类都实现该属性,因为当您不实现抽象属性时,将收到编译器警告。

我还想问,为什么在基类中需要ActionType?这是否意味着您的基类可以根据ActionType(即派生类的类型)具有不同的行为?如果是这样,那么更好的设计是使用多态性,即去掉actionType属性,而是在基类中提供抽象方法,您可以在派生类中重写这些方法以实现派生类特定的行为


我理解这是一个有点做作的示例,因此我的评论可能不适用于您的实际代码。

我还想问,为什么您的基类中需要ActionType?这是否意味着您的基类可以根据ActionType(即派生类的类型)具有不同的行为?如果是这样,那么更好的设计是使用多态性,即去掉actionType属性,而是在基类中提供抽象方法,您可以在派生类中重写这些方法以实现派生类特定的行为


我理解这是一个有点做作的例子,因此我的评论可能不适用于您的实际代码。

所有操作都有ActionType所有操作都有ActionType