2011-06-13 4 views
1

...C# 1 인터페이스 I이 방법을

이 메소드를 호출
public static IList<IOutgoingMessage> CompressMessages(IList<IOutgoingMessageWithUserAndPtMedInfo> msgs) 
    { 
     StoreOriginalMessages(msgs); 
     ... 
    } 

...

private static void StoreOriginalMessages(IList<IOutgoingMessage> msgs) {...} 

IOutgoingMessageWithUserAndPtMedInfo 이렇게 정의 ...

public interface IOutgoingMessageWithUserAndPtMedInfo: IOutgoingMessage 
{ 
    IPatientMedication PatientMedication { get; set; } 
    IUserContainer User{ get; set; } 
} 

CompressMessages 방법에서 StoreOriginalMessages 전화를 걸 때이 오류가 발생합니다.

은 'System.Collections.Generic.IList <MyMediHealth.DataAccess.Containers.IOutgoingMessageWithUserAndPtMedInfo>'에서

이유를 이해하지 마십시오 'System.Collections.Generic.IList <MyMediHealth.DataAccess.Containers.IOutgoingMessage>'로 변환 할 수 없습니다. IOutgoingMessageWithUserAndPtMedInfoIOutgoingMessage에서 상속되기 때문에 받아 들일 것으로 기대합니다.

내가 뭘 잘못하고 있니?

답변

3

귀하의 메서드 이름에서 나는 StoreOriginalMessages가 목록에 새 요소를 삽입하지 않는다고 결론을 냅니까?

당신은

private static void StoreOriginalMessages(IEnumerable<IOutgoingMessage> msgs) 

하여 대체 할 수와 (- 더 공분산 지원은 불행하게도 없었다 전에 C# 4.0이있는 경우)가 원활하게 작동합니다.

는 C# 3.5 일 경우 당신은뿐만 아니라 전화 사이트를 변경해야

StoreOriginalMessages(msgs.Cast<IOutgoingMessage>()); 
+0

3.5에서 작업 중이므로 답변으로 표시했습니다. 감사! – Marvin

5

참조 : 다음 2 인터페이스와 2 개 클래스를 가정 Covariance and Contravariance in Generics

:

interface IBase {} 
interface IDerived : IBase {} 

class Base {} 
class Derived : Base {} 

이 작업을 수행 할 경우 동일한 캐스팅 오류 얻을 것이다 : 그러나

IList<IDerived> lid = null; 
IList<IBase> lib = lid; //cannot cast IList<IDerived> to IList<IBase> 

IList<Derived> ld = null; 
IList<Base> lb = ld; //cannot cast IList<Derived> to IList<Base> 

을, 다음은 이 공분산에 대해 선언 되었기 때.에 IList<T>이 선언되지 않았으므로 잘 컴파일됩니다. IEnumerable<T>은 실제로 IEnumerable<out T>이며, 이는 type 매개 변수가 반환 값 전용임을 나타내고 공분산을 허용 할 수 있음을 나타냅니다.

IEnumerable<IDerived> lid = null; 
IEnumerable<IBase> lib = lid; 

IEnumerable<Derived> ld = null; 
IEnumerable<Base> lb = ld; 
+0

이 100 % 정확합니다. – msarchet

+2

당신은 가장 확실하게 인터페이스로 이것을 할 수 있습니다. IList 은 T에서 공변하지 않습니다. 이것은 IList 이 공 변성 시나리오에서 동작을 깨뜨릴 수있는 Add와 같은 메소드를 노출하기 때문에 이루어졌습니다 (사용중인 기린 컬렉션에 호랑이 추가하기 포유류 컬렉션으로). 대신 IEnumerable 을 사용하면 코드가 정상적으로 작동합니다. –

+0

@Chris : 내 의견이 맞지 않아요. 나는 내 대답을 많이 반복한다. –