2014-12-16 3 views
3

내가 계층 적으로 중첩 된 제네릭 인터페이스의 사슬, 예를 위해 다음과 같이 있습니다를 계층 구조로 중첩 된 제네릭 인터페이스

ICar<TWheels, TBolts> 
where TWheels : IWheels<TBolts> 
where TBolts : IBolts 
{ 
    IEnumerable<TWheels> Wheels { get; set; } 
} 

IWheels<TBolts> 
where TBolts : IBolts 
{ 
    IEnumerable<TBolts> Wheels { get; set; } 
} 

IBolts 
{ 

} 

이 이러한 일반적인 인터페이스를 처리하는 합리적인 방법인가를?

그것은하게 정의하는 방법은 다음과 같이 :

public TCar GetCar<TWheels, TBolts>(int id) 
where TCar : ICar<TWheels, TBolts> 
where TWheels : IWheels<TBolts> 
where TBolts : IBolts 
{ 
    ... 
} 

이 코드 서명을 줄일 수있는 방법이 있나요?

+0

아마도 매개 변수를 메서드 대신 클래스에 정의 할 수 있습니다. (그것들은 물론 정적이 아닌 한) –

+0

당신이'TCar'를 반환하기 때문에, 당신이 본질적으로 당신 자신에 그것을 부과하기 때문에, 당신은 처음'where' 절이 필요하다고 생각하지 않습니다. 처음에 ICar 를 반환한다고 선언하십시오. –

+0

[답변으로 삭제되고 주석으로 게시 됨] - 너무 많은 인터페이스로 인해 문제가 보완되는 것 같습니다. 반 패턴을 사용해보십시오. – Amit

답변

1

C#의 Generics는 직면 한 문제를 피하기 위해 매우 조심스럽게 사용해야합니다. 난 도망 제네릭 인터페이스 계층 구조를 수정하고 던져 권하고 싶습니다 :

interface ICar 
{ 
    IEnumerable<IWheel> Wheels { get; set; } 
} 

interface IWheel 
{ 
    IEnumerable<IBolt> Bolts { get; set; } 
} 

interface IBolt 
{ 
} 

는 그 다음 그 인터페이스가 참여하는 사용 사례,보고 좋은 것입니다.
매우 드문 경우가 있습니다. IWheel 대신 IR16Wheel이 필요하고 캐스팅만으로 충분할 수 있습니다.

interface IWheel<TBolt> : IWheel 
    where TBolt : IBolt 
{ 
    IEnumerable<TBolt> Bolts { get; set; } 
} 

이 같은 방법으로 비 제네릭을 사용합니다 :
는 일반적인 사람과 제네릭이 아닌 인터페이스를 페어링 할 충분한 것, 할 수

public ICar GetCar(int id) { } 

을뿐만 아니라보다 구체적인에서 제네릭을 사용 사례.

+0

죄송합니다. 당신의 대답은 좋은 포인터이지만 "이 코드 서명을 줄이려면 어떤 방법이 있습니까?" 그래서, downvoted. – Amit

+1

@Amit : 재 설계 유형이 유일한 해결책입니다. 너는 완전히 틀렸다. – Dennis

+0

@Amit 질문에 대한 "올바른"답변은 질문자가 다른 방식으로 생각하게 만드는 것입니다. [XY 문제] (http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem)를 참조하십시오. 이 경우에는 "이 코드 서명을 줄이는 방법"에 대한 대답이 있습니다. 대답은 상속 체인을 다시 디자인함으로써 발생합니다. –

관련 문제