Variance는 실제로 CLR이 이미 가지고있는 기능을 사용하여 안전한 방식으로 만 지원됩니다 . 그래서 내가 List<Banana>
a를 List<Fruit>
(또는 그것이 무엇이든) 사용하려는 책에서 제공하는 예제 는 여전히 작동하지 않을 것입니다. 그러나 몇 가지 다른 시나리오는 작동합니다.
첫째, 인터페이스와 델리게이트에 대해서만 지원됩니다.
둘째, 인터페이스 / 대리자의 작성자가 유형 매개 변수를 in
(반 변성의 경우) 또는 out
(공분산의 경우) 로 장식해야합니다 . 가장 명백한 예는 IEnumerable<T>
값을 "밖으로"가져 오도록 허용하는 것입니다. 새 값을 추가 할 수는 없습니다. 그것은 될 것 IEnumerable<out T>
입니다. 이것은 타입 안전성을 전혀 손상시키지 않지만 예를 들어 IEnumerable<string>
반환 IEnumerable<object>
하도록 선언 된 메서드에서 를 반환 할 수 있습니다 .
Contravariance는 인터페이스 사용에 대한 구체적인 예를 제공하기가 더 어렵지만 델리게이트를 사용하면 쉽습니다. 고려하십시오 Action<T>
- T
매개 변수 를 취하는 메소드를 나타냅니다 . 완벽하게 변환 사용할 수 있도록 좋을 것이다 Action<object>
AS를 Action<string>
소요 어떤 방법 - object
매개 변수는이되게 때 벌금을 될 것입니다 string
대신합니다. 물론 C # 2에는 이미 어느 정도 대리자의 공분산 및 반공 변성이 있지만 한 대리자 형식에서 다른 대리자 형식으로의 실제 변환 (새 인스턴스 만들기)을 통해 예를 들어 P141-144를 참조하십시오. C # 4는 이것을 더 일반적으로 만들고 (내 생각에) 변환을위한 새 인스턴스를 만들지 않을 것입니다. (대신 참조 변환이됩니다.)
이로 인해 문제가 해결되기를 바랍니다. 이해가되지 않으면 알려주세요!