2

我正在尝试设置类似于以下的继承层次结构:

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;
}

我只想将 MotorcycleAxle 对象存储在 Motorcycle 对象的 Axles 数组中,并将 CarAxle 对象存储在 Car 对象的 Axles 数组中。问题是没有办法覆盖子类中的数组来强制其中一个。理想情况下,类似以下内容对 Motorcycle 类有效:

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

但是覆盖时类型必须匹配。我怎样才能支持这种架构?我是否只需要在访问 Axles 成员的任何地方进行大量运行时类型检查和转换?我不喜欢添加运行时类型检查,因为您开始失去强类型和多态性的好处。在这种情况下必须至少进行一些运行时检查,因为 WheelAttached 和 Left/RightWheelAttached 属性取决于类型,但我想最小化它们。

4

3 回答 3

5

使用更多泛型

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;
}
于 2008-08-27T20:10:28.373 回答
0

2个选项浮现在脑海。1 使用泛型:

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

第二个使用阴影 - 这假设你有属性:

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>

阴影的问题在于您有一个通用列表。不幸的是,您不能将列表限制为仅包含 CarAxle。此外,您不能将 List<Axle> 转换为 List<CarAxle> - 即使那里有一个继承链。您必须将每个对象转换为一个新列表(尽管使用 LINQ 会变得更容易)。

我自己会去仿制药。

于 2008-08-27T20:54:11.593 回答
0

我问了一个类似的问题,得到了更好的答案,这个问题与 C# 对协变和逆变的支持有关。有关更多信息,请参阅该讨论。

于 2008-09-05T22:21:41.823 回答