C# 일반적인 제약 조건에도 불구하고 변환 오류
-
06-07-2019 - |
문제
"A에서 나와 상속 해야하는"클래스 P의 유형 매개 변수 t에 대한 일반적인 제약 조건으로 첫 번째 호출이 성공하지만 두 번째 호출은 주석에 자세히 설명 된 유형 변환 오류로 실패합니다.
abstract class A { }
static class S
{
public static void DoFirst(A argument) { }
public static void DoSecond(ICollection<A> argument) { }
}
static class P<T>
where T : A, new()
{
static void Do()
{
S.DoFirst(new T()); // this call is OK
S.DoSecond(new List<T>()); // this call won't compile with:
/* cannot convert from 'System.Collections.Generic.List<T>'
to 'System.Collections.Generic.ICollection<A>' */
}
}
일반적인 제약 조건이이를 보장해서는 안됩니다 List<T>
~이다 참으로 ICollection<A>
?
해결책
이것은 C#의 부족의 예입니다. 공분산 일반 유형 (C# 하다 배열 공분산 지원). C# 4는이 기능을 인터페이스 유형에 추가하고 여러 BCL 인터페이스 유형을 업데이트하여 지원합니다.
참조하십시오 C# 4.0 : 공분산 및 비밀화:
이 기사에서는 C# 4.0 혁신 중 하나를 다루려고합니다. 새로운 기능 중 하나는 현재 일반 대표 및 일반 인터페이스에서 지원하는 유형 매개 변수에 대한 공분산 및 분열입니다. 먼저이 단어가 무엇을 의미하는지 보자 :)
다른 팁
제약은 문제에 영향을 미치지 않습니다. 문제는 icollection이 필요한 매개 변수로 목록을 전달한다는 것입니다.-c#은 공분산을 지원하지 않으므로 목록을 iCollection에 명시 적으로 시전해야합니다.
S.DoSecond((ICollection<A>) new List<T>()); // this call will be happy
유형의 iCollection으로 선량에 대한 매개 변수를 강력하게 입력했습니다 u003CA>. t가 유형 A라는 사실에도 불구하고, 컴파일 시간에u003C/a> 절대적인 목록 사이에 캐스트u003CT> 그리고 icollection u003CA>.u003C/a> Dosecond를 호출 할 때 u003CA>목록을 작성하고 ICollection에 캐스트u003C/a> u003CA>하거나 Dosecond를 일반 방법 자체로 만들어야합니다.u003C/a>
참고 :이 유형의 암시 적 캐스트는 C# 4.0에서 지원되어야하며, 이는 C# 3.0이 제공하는 것보다 훨씬 개선 된 CO/비정형을 제공합니다.