C #에서 제네릭과 공분산의 공분산 이해 문제
다음 C # 코드가 컴파일되지 않는 이유를 이해할 수 없습니다.
보시다시피, 정적 제네릭 메서드 IEnumerable<T>
매개 변수 T
가있는 IA
인터페이스 가 있고 인터페이스로 제한되어 있으며이 매개 변수는 암시 적으로로 변환 할 수 없습니다 IEnumerable<IA>
.
설명은 무엇입니까? (어떻게 작동하지 않는지 이해하기 위해 해결 방법을 검색하지 않습니다).
public interface IA { }
public interface IB : IA { }
public class CIA : IA { }
public class CIAD : CIA { }
public class CIB : IB { }
public class CIBD : CIB { }
public static class Test
{
public static IList<T> Something<T>(IEnumerable<T> foo) where T : IA
{
var bar = foo.ToList();
// All those calls are legal
Something2(new List<IA>());
Something2(new List<IB>());
Something2(new List<CIA>());
Something2(new List<CIAD>());
Something2(new List<CIB>());
Something2(new List<CIBD>());
Something2(bar.Cast<IA>());
// This call is illegal
Something2(bar);
return bar;
}
private static void Something2(IEnumerable<IA> foo)
{
}
}
Something2(bar)
줄에 오류가 있습니다.
인수 1 : 'System.Collections.Generic.List'에서 'System.Collections.Generic.IEnumerable'로 변환 할 수 없습니다
오류 메시지는 정보가 충분하지 않으며 내 잘못입니다. 미안합니다.
공분산은 참조 유형에서만 작동한다는 사실 때문에 발생하는 문제입니다.
아마도 IA
"지금은 참조 유형입니다" 라고 말하고있을 것입니다 . 그렇습니다. 그러나 당신은 그것이 T
같다고 말하지 않았습니다 IA
. 당신은 상기 T
한 종류입니다 구현 IA
하고, 값 유형이 인터페이스를 구현할 수 있습니다 . 따라서 공분산이 작동하는지 알 수 없으므로 허용하지 않습니다.
공분산이 작동하려면 컴파일러에 type 매개 변수가 인터페이스 제약 조건 class
뿐만 아니라 제약 조건 이있는 참조 유형임을 알려 주어야합니다 IA
.
공분산에 기준 유형 보장이 필요하기 때문에 변환이 불가능하다는 오류 메시지가 표시되어야합니다. 이것이 근본적인 문제이기 때문입니다.
나는 Eric의 훌륭한 내부자 답변을 일반적인 제약 조건에 익숙하지 않은 사람들을위한 코드 예제로 보완하고 싶었습니다.
다음 Something
과 같이 Change 's signature : class
제약 조건 이 먼저 나와야 합니다.
public static IList<T> Something<T>(IEnumerable<T> foo) where T : class, IA
'development' 카테고리의 다른 글
Retrofit-Android로 요청 및 응답 본문을 기록하는 방법은 무엇입니까? (0) | 2020.07.20 |
---|---|
C ++ 03과 C ++ 11의 런타임에 어떤 차이가 감지 될 수 있습니까? (0) | 2020.07.20 |
소스 코드를 자동으로 들여 쓰는 방법? (0) | 2020.07.20 |
React 컴포넌트에서 컴포넌트 기본 소품을 설정하는 방법 (0) | 2020.07.20 |
C # 4.0 : TimeSpan을 기본값을 가진 선택적 매개 변수로 사용할 수 있습니까? (0) | 2020.07.20 |