문제

아래와 같이 정의된 인터페이스가 있습니다.

public interface TestInterface{
    int id { get; set; }
}

그리고 해당 인터페이스를 구현하는 두 개의 Linq-to-SQL 클래스는 다음과 같습니다.

public class tblTestA : TestInterface{
    public int id { get; set; }
}

public class tblTestB : TestInterface{
    public int id { get; set; }
}

tblTestA 및 tblTestB의 데이터베이스 레코드로 채워진 IEnumerable 목록 a 및 b가 있습니다.

IEnumerable<tblTestA> a = db.tblTestAs.AsEnumerable();
IEnumerable<tblTestB> b = db.tblTestBs.AsEnumerable();

그러나 다음은 허용되지 않습니다.

List<TestInterface> list = new List<TestInterface>();
list.AddRange(a);
list.AddRange(b);

다음과 같이 해야 합니다.

foreach(tblTestA item in a)
    list.Add(item)

foreach(tblTestB item in b)
    list.Add(item)

내가 잘못하고 있는 것이 있나요?어떤 도움을 주셔서 감사합니다

도움이 되었습니까?

해결책

일반 공분산 으로 인해 C # 4에서 작동합니다. C #의 이전 버전과 달리 IEnumerable<tblTestA>에서 IEnumerable<TestInterface>로 변환이 있습니다.

기능은 V2에서 CLR에 있었지만 C # 4에만 노출되었습니다 (그리고 프레임 워크 유형은 .NET 4 이전에이를 활용하지 않았습니다). 은 일반적인 인터페이스 및 대리인 (클래스가 아님)에만 적용되며 참조 유형에만 적용됩니다 (예 : IEnumerable<int>에서 IEnumerable<object>에서 IEnumerable<T> 로의 변환이 없습니다. 오브젝트는 API의 "out"만 있지만, IList<T>는 해당 API와 함께 값을 추가 할 수 있기 때문에 불변 입니다.

일반적인 상반기도 지원되어 다른 방향으로 작동합니다. 예를 들어 IComparer<object>에서 IComparer<string>로 변환 할 수 있습니다.

C # 4를 사용하지 않으면 TIM의 Enumerable.Cast<T>를 사용하는 TIM의 제안은 좋은 것입니다 - 당신은 약간의 효율을 잃지 만 작동합니다.

일반적인 분산에 대해 자세히 알고 싶다면 Eric Lippert는 NDC 비디오 페이지 .

다른 팁

당신은 아무것도 하지 않고 잘못된: List<TestInterface>.AddRange 기대하는 IEnumerable<TestInterface>.그것을 받아들이지 않을 것인 IEnumerable<tblTestA>IEnumerable<tblTestB>.

귀하의 foreach 루프를 작동합니다.또는 사용할 수 있습니다 Cast 을 변경하는 유형:

List<TestInterface> list = new List<TestInterface>();
list.AddRange(a.Cast<TestInterface>());
list.AddRange(b.Cast<TestInterface>());

addRange는 인터페이스 개체 목록을 기대하고 "a"와 "b"varaibles는 파생 클래스 객체 목록으로 정의됩니다.분명히 .NET은 논리적으로 인터페이스를 구현하기 때문에 인터페이스 객체 목록으로 점프하고 대우 할 수 있으므로 논리가 3.5에서 .NET로 빌드되지 않기 때문에 인터페이스 객체 목록으로 점프하고 대우 할 수 있습니다.

그러나이 능력 ( "공분산"이라고 함)은 .NET 4.0에 추가되었지만, 그로 인해 업그레이드 할 때까지 루핑을 통해 멈추거나 toarray ()를 호출 한 다음 결과를TaskInterface [] 또는 Adere Linq 쿼리가 각 항목을 대소 문자로 만들고 새 목록을 만듭니다.

a 그리고 b 유형이다 IEnumerable<tblTestA> 그리고 IEnumerable<tblTestB>
하는 동안 list.AddRange 매개변수는 유형이어야 합니다. IEnumerable<TestInterface>

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top