【问题标题】:Specify field type in derived class在派生类中指定字段类型
【发布时间】:2021-02-17 07:27:00
【问题描述】:

出于向后兼容性的原因,我有一个 Rectangle2d 和一个 Rectangle3d 派生自它。这样做时,类的“transform”字段的类型将从 Transform2d 更改为 Transform3d,这是 Transform2d 的派生版本。 这是一个简化的示例:

class Transform2
{
    protected float positionX;
    protected float positionY;
}

class Transform3 : Transform2
{
    protected float positionZ;
}


class Rectangle2d
{
    protected Transform2 transform;
}

class Rectangle3d : Rectangle2d
{
    // Does not work: Just hides Rectangle2d.transform
    protected new Transform3 transform;
}

我不喜欢的一个解决方案是不使用 Transform 类和直接字段:

class Rectangle2d
{
    protected float positionX;
    protected float positionY;
}

class Rectangle3d : Rectangle2d
{
    protected float positionZ;
}

在我看来,当第二种方法有效并且第一种方法只是第二种方法并带有一些聚束时,应该有一个干净的解决方案。至少它希望如此。

版本:.NET Framework 4.6.1

【问题讨论】:

  • 您的继承在 imo 中没有多大意义。 3D 变换/对象比 2D 更通用...如果您以其他方式进行操作,则问题会更少(例如,变换 2d 实际上是变换 3d,其中 z 固定为零等)
  • Rectangle3d 从 2d 对应物继承没有意义 - 那是你的问题!
  • 这里的继承关系都没有意义,2D 形状也不是 3D 形状,3D 形状也不是 3D 形状。
  • @HimBromBeere 2D 形状是深度为 0 的 3D 形状
  • 感谢您的回答。只是为了理解:在我的应用程序中,我主要使用 2d 对象。 3d 对象很少见,但它们就在那里。当我从 3d 对象派生 2d 时,这更有意义,但我也会得到我想要防止的巨大开销。

标签: c# field derived-class


【解决方案1】:

您要求的是不可能的,字段不能被覆盖。这就是为什么公开可见(并且protected 是公开可见的)字段受到设计指南的鼓励的部分原因。不过,您可以将其抽象为一个属性:

class Rectangle2d
{
    private Transform2d transform;

    protected virtual Transform2d Transform => transform;
} 

class Rectangle3d
{
    private Transform3d transform;

    protected override Transform2d Transform => transform;
} 

理想情况下,您的基类应尽可能少地依赖具体的transform 字段,而应使用Transform 属性。但是,作为设计建议,请考虑将常见行为抽象为 abstract RectangleBase 并让 2D 和 3D 变体从它继承,而不是从彼此继承。您现在正在从Rectangle2d 创建一个相当脆弱的基类。

【讨论】:

    【解决方案2】:

    继承意味着is-a 关系。 Rectangle3d 不是 2d,所以它可能不应该继承自 Rectangle2d

    也就是说,如果你必须这样做,我建议你使用泛型

    public abstract class Transform<T>
    {
        protected T transform;
    }
    
    public class Rectangle2d : Transform<Transform2> {}
    public class Rectangle3d : Transform<Transform3> {}
    

    在这个模型中,2d 和 3d 都有一个属性 transform,它是强类型的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-27
      • 2014-06-16
      相关资源
      最近更新 更多