简体   繁体   English

继承需要存储特定于子类的数据的数组的最佳方法是什么?

[英]What is the best way to inherit an array that needs to store subclass specific data?

I'm trying to set up an inheritance hierarchy similar to the following: 我正在尝试建立类似于以下内容的继承层次结构:

abstract class Vehicle
{
  public string Name;
  public List<Axle> Axles;
}

class Motorcycle : Vehicle
{
}

class Car : Vehicle
{
}

abstract class Axle
{
  public int Length;
  public void Turn(int numTurns) { ... }
}

class MotorcycleAxle : Axle
{
  public bool WheelAttached;
}

class CarAxle : Axle
{
  public bool LeftWheelAttached;
  public bool RightWheelAttached;
}

I would like to only store MotorcycleAxle objects in a Motorcycle object's Axles array, and CarAxle objects in a Car object's Axles array. 我只想将MotorcycleAxle对象存储在Motorcycle对象的Axles数组中,而将CarAxle对象存储在Car对象的Axles数组中。 The problem is there is no way to override the array in the subclass to force one or the other. 问题是没有办法重写子类中的数组来强制一个或另一个。 Ideally something like the following would be valid for the Motorcycle class: 理想情况下,类似于以下内容对Motorcycle类有效:

class Motorcycle : Vehicle
{
  public override List<MotorcycleAxle> Axles;
}

but the types have to match when overriding. 但类型必须在覆盖时匹配。 How can I support this architecture? 我如何支持这种架构? Will I just have to do a lot of run-time type checking and casting wherever the Axles member is accessed? 在访问Axles成员的任何地方,我是否都需要做很多运行时类型检查和转换? I don't like adding run-time type checks because you start to lose the benefits of strong typing and polymorphism. 我不喜欢添加运行时类型检查,因为您开始失去了强类型和多态性的好处。 There have to be at least some run-time checks in this scenario since the WheelAttached and Left/RightWheelAttached properties depend on the type, but I would like to minimize them. 在这种情况下,至少必须进行一些运行时检查,因为WheelAttached和Left / RightWheelAttached属性取决于类型,但是我想将它们最小化。

Use more generics 使用更多泛型

abstract class Vehicle<T> where T : Axle
{
  public string Name;
  public List<T> Axles;
}

class Motorcycle : Vehicle<MotorcycleAxle>
{
}

class Car : Vehicle<CarAxle>
{
}

abstract class Axle
{
  public int Length;
  public void Turn(int numTurns) { ... }
}

class MotorcycleAxle : Axle
{
  public bool WheelAttached;
}

class CarAxle : Axle
{
  public bool LeftWheelAttached;
  public bool RightWheelAttached;
}

2 options spring to mind. 想到两个选择。 1 is using generics: 1正在使用泛型:

abstract class Vehicle<TAxle> where TAxle : Axle {
   public List<TAxle> Axles;
}

The second uses shadowing - and this assumes you have properties: 第二个使用阴影-并假设您具有属性:

abstract class Vehicle {
   public IList<Axle> Axles { get; set; }
}

class Motorcyle : Vehicle {
   public new IList<MotorcycleAxle> Axles { get; set; }
}

class Car : Vehicle {
   public new IList<CarAxle> Axles { get; set; }
}

void Main() {
   Vehicle v = new Car();
   // v.Axles is IList<Axle>

   Car c = (Car) v;
   // c.Axles is IList<CarAxle>
   // ((Vehicle)c).Axles is IList<Axle>

The problem with shadowing is that you have a generic List. 遮盖的问题是您有一个通用列表。 Unfortunately, you can't constrain the list to only contain CarAxle. 不幸的是,您不能将列表限制为仅包含CarAxle。 Also, you can't cast a List<Axle> into List<CarAxle> - even though there's an inheritance chain there. 另外,即使那里有继承链,也不能将List <Axle>强制转换为List <CarAxle>。 You have to cast each object into a new List (though that becomes much easier with LINQ). 您必须将每个对象转换为新的List(尽管使用LINQ变得容易得多)。

I'd go for generics myself. 我会自己去买仿制药。

I asked a similar question and got a better answer, the problem is related to C#'s support for covariance and contravariance. 我问了一个类似的问题,并且得到了一个更好的答案,该问题与C#对协方差和反方差的支持有关。 See that discussion for a little more information. 有关更多信息,请参见该讨论。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM