Что задумывалось за проектным решением не реализовывать дисперсию в типовых типовых классах? Разве это невозможно, нежелательно или входит в список «возможно, один день»?
Вы в хорошей компании; Джон Скит и Билл Вагнер задали мне тот же вопрос пару недель назад. Я работал над сообщением в блоге, но кратко:
Правильный человек, который попросит дать окончательный ответ, - Эндрю Кеннеди из Microsoft Research Cambridge, который первоначально разработал и внедрил большую часть общей логики и логики отклонений. Тем не менее, я могу подвергнуть сомнению обоснованное предположение о том, почему мы решили отказаться от различий в общих классах.
Короткая версия: Безопасная ковариация T требует, чтобы операции над T были «только для чтения». Контравариантность T требует, чтобы операции над T были «только для записи». У вас есть класс C<T>
, который вы хотите изменить в T. Предположим, `C имеет поле типа T: вы хотите, чтобы это поле было только для чтения или только для записи ? Потому что это ваш выбор!
При каких обстоятельствах даже смутно полезно иметь поле, в которое можно записывать, но не читать? Не много. При каких обстоятельствах полезно иметь поле, которое может быть прочитано, но не записано? Только если поле помечено только для чтения .
Короче говоря, контравариантные универсальные классы почти никогда не полезны, потому что вы не можете читать из них никаких универсальных данных, а ковариантные классы в основном полезны, только если класс является неизменным типом данных .
Я большой поклонник неизменяемых типов данных, и я думаю, что было бы замечательно иметь возможность создавать ковариантный неизменяемый стек без использования интерфейса. Но ковариантные универсальные постоянные неизменяемые функциональные структуры данных еще не совсем распространены в C #, и они, конечно, не были такими, когда генерики были добавлены в CLR. Более того, у нас нет вспомогательной инфраструктуры, кроме полей только для чтения, чтобы выразить понятие «это неизменяемый тип данных» в C # или CLR; если бы мы делали ковариантные типы классов для неизменяемых классов, было бы неплохо сделать лотов функций, которые поддерживают неизменяемые классы, а не только этот неясный.
Итак, я вижу, как эта функция не выполняла разрез в CLR 2.0 / C # 2.0. Если бы мы проектировали его снова сегодня, когда программирование в функциональном стиле несколько более популярно, возможно, так и было бы. Но у нас нет планов делать это в ближайшее время.
В ближайшие несколько месяцев я напишу сообщение в блоге, в котором будет дан более подробный ответ.