Как реализуется общая ковариация и контра-дисперсия в C# 4.0?
Я не присутствовал на PDC 2008, но я слышал некоторые новости о том, что C# 4.0 объявлен для поддержки общей ковариации и контра-дисперсии. То есть, List<string>
может быть назначено List<object>
. Как такое может быть?
в книге Джона Скита C# в глубину, объясняется, почему c# generics не поддерживает ковариацию и контра-дисперсию. Это в основном для написания безопасного кода. Теперь, C# 4.0 изменился, чтобы поддержать их. Принесет ли это хаос?
кто-нибудь знает подробности о C# 4.0 могут дать некоторое объяснение?
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