2008-08-27 71 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#支持協變和逆變有關。請參閱該討論以獲取更多信息。