2008-08-27 1 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 개체에. 문제는 하위 클래스의 배열을 재정 의하여 하나 또는 다른 것을 강제 할 수있는 방법이 없다는 것입니다. 이상적으로 다음과 같은 내용이 Motorcycle 클래스에 유효합니다.

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

이 옵션이 마음에 봄.

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>에 캐스트 할 수 없습니다. 거기에 상속 체인이 있어도 마찬가지입니다. 각 개체를 새 List로 캐스팅해야합니다 (LINQ를 사용하면 훨씬 쉽습니다).

나는 제네릭을 직접 먹을 것입니다.

0

나는 similar question을 물었고 더 좋은 대답을 얻었습니다. 문제는 공분산과 반공립에 대한 C#의 지원과 관련이 있습니다. 좀 더 자세한 정보는 토론을 참조하십시오.

관련 문제