[c#] Generic Covariance & Contra-variance는 C # 4.0에서 어떻게 구현됩니까?

PDC 2008에는 참석하지 않았지만 C # 4.0이 Generic covariance와 contra-variance를 지원하기 위해 발표되었다는 소식을 들었습니다. 즉,에 List<string>할당 할 수 있습니다 List<object>. 어떻게 그럴 수 있습니까?

Jon Skeet의 저서 C # in Depth 에서는 C # 제네릭이 공분산 및 반 분산을 지원하지 않는 이유를 설명합니다. 주로 보안 코드를 작성하기위한 것입니다. 이제 C # 4.0이이를 지원하도록 변경되었습니다. 혼란을 가져올까요?

C # 4.0에 대한 세부 정보를 아는 사람이 몇 가지 설명을 제공 할 수 있습니까?



답변

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는 이것을 더 일반적으로 만들고 (내 생각에) 변환을위한 새 인스턴스를 만들지 않을 것입니다. (대신 참조 변환이됩니다.)

이로 인해 문제가 해결되기를 바랍니다. 이해가되지 않으면 알려주세요!


답변

Jon이 아직 다루지 않았지만 Eric Lippert의 블로그와 비디오에 대한 링크가 있습니다. 그는 예를 들어 설명하는 훌륭한 일을합니다.

https://blogs.msdn.microsoft.com/ericlippert/2007/10/16/covariance-and-contravariance-in-c-part-one/

동영상 :

https://www.youtube.com/watch?v=3MQDrKbzvqU

https://www.youtube.com/watch?v=XRIadQaBYlI

https://www.youtube.com/watch?v=St9d2EDZfrg


답변