2008-08-27 68 views
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对象的摩托车对象的车轴阵列,并CarAxle对象在汽车对象的车轴阵列。问题是没有办法重写子类中的数组来强制一个或另一个。理想情况下,类似以下内容对于摩托车类别将是有效的:

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

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

回答

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; 
} 
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。此外,您不能将列表<车轴>转换成列表<CarAxle> - 即使在那里存在继承链。你必须将每个对象转换成一个新的List(尽管LINQ变得更容易)。

我会去为仿制药自己。

0

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