2008-08-27 4 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; 
} 

私は希望Carオブジェクトの車軸配列内の唯一のオートバイのオブジェクトの車軸配列に格納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オプションの心に春。第二の用途は、シャドーイング

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

- これはあなたがプロパティを持っている前提としています:1は、ジェネリックを使用している

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だけを含むようにリストを制約することはできません。また、リスト<Axle>をリストにキャストすることはできません<CarAxle> - そこに継承チェーンがあります。各オブジェクトを新しいリストにキャストする必要があります(LINQのほうがはるかに簡単です)。

私はジェネリック医薬品を手にしています。

0

私はsimilar questionと尋ねましたが、より良い答えを得ました。この問題は、共分散と反動のC#のサポートに関連しています。もう少し詳しくは、そのディスカッションを参照してください。

関連する問題