2013-04-11 1 views
2

서브 클래스 타입의 매개 변수 인터페이스 메소드를 구현 어떻게해야합니까?C#을 나는이 원하는 클래스 계층이 한

+0

인터페이스 자체를 일반화하고 구현 클래스에 원하는 유형을 제공해야합니다. – Rik

+1

print 메소드에서 매개 변수를 가지지 않고 각 하위 클래스가 IClass 구현을 생성자 또는 서터에 주입하도록하는 방법은 어떻습니까? –

+1

toString 메서드는 Object에서 상속되므로, 왜'print (Object item)'뿐만 아니라'print (MyClass item)'을 정말로 필요로합니까? 이 방법을 숨기시겠습니까? – Thomas

답변

11

당신은 당신의 방법에 매개 변수로 ICLASS을 통과해야

interface IClass<T> where T : IClass<T> 
{ 
    string print(T item); 
} 

class MyClass : IClass<MyClass> 
{ 
    public string print(MyClass item) 
    { 
     return item.ToString(); 
    } 
} 
+0

@Mehmet Ataş, 내 목숨을 구해 주셔서 감사합니다. 작동합니다. – Lio

+2

작동하지만, (1) 혼란스럽고 (2) 시행 할 제한을 반드시 이행하지는 않습니다. 이 패턴에 대한 의견을 보려면 http://blogs.msdn.com/b/ericlippert/archive/2011/02/03/curiouser-and-curiouser.aspx를 참조하십시오. –

+0

@ Eric, 문제를보다 명확하게 해결하기 위해 무엇을 제안 하시겠습니까? – Lio

0

사용자 인터페이스는 일반적인합니다.

interface IClass 
{ 
    string print(IClass item); 
} 

class MyClass : IClass 
{ 
    public string print(IClass item) 
    { return item.ToString(); } 
} 
+1

내 요구 사항은 MyClass의 인쇄 메소드가 다른 IClass 서브 클래스가 아닌 MyClass 매개 변수를 정확히 받아야한다는 것입니다. – Lio

+0

지금은 구현이 아닌 인터페이스에 프로그래밍해야한다는 것을 무시하면됩니다. 다음 인터페이스에 문제가 있습니까? 인터페이스 IClass {string print (MyClass item); } – WPFAbsoluteNewBie

+0

아무 것도. 괜찮아. 그러나 @Eric Lippert 아래서는 혼란 스럽다. – vcRobe

7

왜 이것이 불법인지 이해하는 것이 도움이됩니다. 원하는 기능은 형식 매개 변수 유형 공분산이며 매우 적은 언어로 제공됩니다. (에펠, 나는 이것을 특징으로 생각한다.) 안전하지 않기 때문에 언어에서 자주 발견되지 않는다! 예를 들어 설명해 드리겠습니다.

class Animal {} 
class Lion : Animal { public void Roar() { } } 
class Giraffe : Animal { } 
interface IFoo { void M(Animal a); } 
class C : IFoo 
{ 
    public void M(Lion lion) { lion.Roar(); } 
} 
class P 
{ 
    public static void Main() 
    { 
     IFoo foo = new C(); 
     foo.M(new Giraffe()); 
    } 
} 

그리고 우리는 방금 기린을 포효했습니다.

모든 유형 변환을 살펴보면 합법적으로 불법으로 만들 수있는 유일한 것은 C.M(Giraffe)에서 IFoo.M(Animal)까지입니다.

지금, 형식 매개 변수 유형 contravariance형태 보증이지만 아주 제한적인 경우를 제외하고 C#에서 불법입니다. C#이 지원하지 않는다면 다음과 같이 안전하게 할 수 있습니다.

interface IBar { void M(Giraffe g); } 
class D : IBar 
{ 
    public void M(Animal animal) { ... } 
} 
class P 
{ 
    public static void Main() 
    { 
     IBar bar = new D(); 
     bar.M(new Giraffe()); 
    } 
} 

무슨 일이 있었는지 확인하십시오. IFoo.M은 "나는 기린을 가져갈 수있다"고 말하면서 C.M은 "실제로 어떤 동물도 받아 들일 수 있기 때문에 나는 어떤 기린도 받아 들일 수있다"고 말합니다. C#에서 지원하는 경우 형식이 안전하지만 두 가지 방식으로 만 지원됩니다.

  • 반올림 범용 대리인 및 인터페이스 변환.
  • 대리자 유형에 대한 반 변형 방법 그룹 변환. 기린를 비교하는 방법이 요구되는 경우 사용될 수 개의 동물을 비교하는 방법

제의 예는 타입 IComparable<Animal>의 표현은 동일한 로직 타입 IComparable<Giraffe>의 변수에 할당 될 수 있다는 . 이것은 C 번호 제

제의 예에서 첨가하는 단계이다

delegate void MyFunction(Giraffe g); 
... 
D d = new D(); 
MyFunction myfunc = d.M; 

다시, 기린을 취하는 함수가 필요하고, 우리는 모든 동물을 얻어 하나를 공급한다. 이 기능은 C# 2에 추가되었습니다.

관련 문제