继承需要存储子类特定数据的数组的最佳方法是什么?
时间:2020-03-05 18:44:05 来源:igfitidea点击:
我正在尝试建立类似于以下内容的继承层次结构:
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属性取决于类型,但是我想将它们最小化。
解决方案
回答
使用更多泛型
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个选项。 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>。我们必须将每个对象转换为新的List(尽管使用LINQ变得容易得多)。
我会自己去买仿制药。
回答
我问了一个类似的问题,并且得到了一个更好的答案,该问题与C#对协方差和反方差的支持有关。有关更多信息,请参见该讨论。