我正在尝试设置类似于以下内容的继承层次结构:
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;
}
我想只在Motorcycle对象的Axles数组中存储MotorcycleAxle对象,在Car对象的Axles数组中存储CarAxle对象。问题是没有办法覆盖子类中的数组来强制一个或另一个。理想情况下,以下内容对摩托车类有效:
class Motorcycle : Vehicle
{
public override List<MotorcycleAxle> Axles;
}
但是在覆盖时必须匹配类型。我该如何支持这种架构?在Axles成员访问的任何地方,我是否只需要进行大量的运行时类型检查和转换?我不喜欢添加运行时类型检查,因为你开始失去强类型和多态的好处。在这种情况下必须至少进行一些运行时检查,因为WheelAttached和Left / RightWheelAttached属性取决于类型,但我想最小化它们。
答案 0 :(得分: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;
}
答案 1 :(得分:0)
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>
阴影的问题在于你有一个通用的List。不幸的是,您不能将列表限制为仅包含CarAxle。此外,您无法转换列表&lt; Axle&gt;进入List&lt; CarAxle&gt; - 即使那里有一个继承链。您必须将每个对象转换为一个新的List(尽管使用LINQ会变得更容易)。
我自己会去寻找仿制药。
答案 2 :(得分:0)
我问similar question并得到了更好的答案,问题与C#对协方差和逆变的支持有关。请参阅该讨论以获取更多信息。