2009-09-08 5 views
0

나는 다음과 같은 인터페이스를 데에 인터페이스를 상속 은 변환 할 수 없습니다 'System.Collections.Generic.IList<IDerived>'에서 'System.Collections.Generic.IList<IBase>'패스하는 방법

목록이 아닌 하나의 인스턴스 만 전달하려는 경우 작동하지만 여기에 무엇이 누락되어 있습니까?

감사합니다,

+0

C#에서'base'는 예약 된 키워드가 아닙니까? – aolde

+0

일주일에 한 번씩 누군가가 공분산에 관한 질문을하지 않습니다. –

답변

3

IBase에 IList 항목을 캐스팅해야합니다. 인자와의 인터페이스를 모두 아직

Check(derived.Cast<IBase>()); 
+0

이것은 "확인"메서드 매개 변수를 IEnumerable <> 대신 IList <>로 변경 한 경우에만 작동하는 것으로 보입니다. (IList <>는 IEnumerable <>을 구현합니다. – nirpi

+0

죄송합니다. 아직 이른 아침에 ... ToList()를 추가하면 문제가 해결되었습니다. Check (derived.Cast () .ToList()); 감사합니다. – nirpi

3

이 C# 3의 인터페이스 유형에 대한 공분산의 부족 때문이다가, C는 # 4 당신이 인터페이스 유형에 대한 공분산 및 contravariance을 지정할 수 있습니다.

불행하게도 이것은 단지 당신이 IList<IDerived>의 인스턴스가 IList<IBase>의 인스턴스가 아닌 C#을 3

2

에서와해야한다고 생각하는 방법을 작동하지 않는 것들 중 하나입니다. 우선, .Add(new ConcreteBase())에 전화 할 수 없습니다. (ConcreteBaseIBase을 구현합니다.)

+0

.Add (new ConcreteBase())는 "기본 유형"참조를 사용하여 "파생 인스턴스"를 전달하는 것과 동일하지 않습니다. –

0

그리고이 작동합니다 ... 몇 가지 이유의

static void Main(string[] args) 
    { 
     List<IDerived> derived = null; 
     Check(derived.ToArray()); 
    } 

    static void Check(IBase[] asdf) 
    { 
    } 

하나는 내가 원시 배열 [] 또는 IEnumerable을 <을 선호> : 여기서의 LINQ 확장을 사용하여 예입니다 반환 값. 그러나 List/IList를 사용하는 것을 선호한다면 다음을 수행 할 수 있습니다.

static void Main(string[] args) 
    { 
     IList<IDerived> derived = null; 
     Check(derived); 
    } 

    static void Check<T>(IList<T> asdf) where T : IBase 
    { 
    }