Как реализуется общая ковариация и контра-дисперсия в C# 4.0?


Я не присутствовал на PDC 2008, но я слышал некоторые новости о том, что C# 4.0 объявлен для поддержки общей ковариации и контра-дисперсии. То есть, List<string> может быть назначено List<object>. Как такое может быть?

в книге Джона Скита C# в глубину, объясняется, почему c# generics не поддерживает ковариацию и контра-дисперсию. Это в основном для написания безопасного кода. Теперь, C# 4.0 изменился, чтобы поддержать их. Принесет ли это хаос?

кто-нибудь знает подробности о C# 4.0 могут дать некоторое объяснение?

2 104

2 ответа:

дисперсия будет поддерживаться только в безопасное путь-фактически, используя способности, которые уже есть в CLR. Поэтому примеры, которые я даю в книге, пытаясь использовать List<Banana> Как List<Fruit> (или что бы это ни было) по - прежнему не будет работать-но несколько других сценариев будет.

во-первых, он будет поддерживаться только для интерфейсов и делегатов.

во-вторых, он требует, чтобы автор интерфейса / делегата украсил параметры типа как in (для контравариантность) или out (для ковариации). Самый очевидный пример -IEnumerable<T> который только когда - либо позволяет вам принимать значения "из" его-это не позволяет добавлять новые. Что станет IEnumerable<out T>. Это не повредит безопасности типа вообще, но позволяет вернуть IEnumerable<string> из метода, объявленного для возврата IEnumerable<object> например.

контравариантность сложнее дать конкретные примеры для использования интерфейсов, но это легко с делегатом. Рассмотрим Action<T> - это просто представляет собой метод, который принимает

Не то, чтобы Джон уже не освещал его, но вот некоторые ссылки на блоги и видео от Эрика Липперта. Он прекрасно объясняет это на примерах.

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