#c_sharp #generics #clr
Почему только интерфейсы и делегаты в C# поддерживают технику ковариантности и контрвариантности в Generic типах?
Ответы
Ответ 1
Хороший вопрос. Простой, поверхностный ответ — потому что это до сих пор не было имплементировано в языке. Но возникает вопрос, почему это не было имплементировано? Смотрите. Дел в том, что C# появился как чисто императивный язык, в котором основной тип структур данных — мутабельные (то есть, изменяемые) структуры данных. Теперь представьте себе, что у вас есть класс C. Что вы будете делать с типом T? Вы не можете иметь метод с входным параметром типа T. Потому что вследствие out у вас может в качестве входного параметра реально прийти тип, базовый для T (по смыслу контравариантности, поэтому-то и используется ключевое слово out: T может встречаться только в «исходящих» позициях, в качестве возвращаемого значения). То же относится и к публичным свойствам типа T с сеттером (и полям), т. к. это по сути та же функция, принимающая на вход T. Вы не сможете иметь полезное приватное мутабельное поле типа T. Почему? Подумайте, как вы присвоите ему какое-нибудь новое значение. Откуда вы его возьмёте? У вас нету методов, которые принимают на вход T, по описанным причинам, вы можете лишь самостоятельно сконструировать экземпляр. Так что ваше поле типа T будет скорее всего бесполезно. Без мутабельных полей типа T, много ли будет пользы от такого параметра? Вот поэтому разработчики языка и решили не заморачиваться с поддержкой контравариантности для классов. С ковариантностью по сути та же история, только вместо невозможности записи в поле типа T вы столкнётесь с невозможностью чтения из него: ко- и контравариантность симметричны. Сейчас язык C# развивается в сторону большей поддержки функционального стиля программирования, в котором популярны иммутабельные (неизменяемые) структуры данных. Если ваша структура данных иммутабельна, вы вполне можете сделать её контравариантной по параметру. Пример лучше всего посмотреть здесь (+T читать как out T). Поэтому стоит рассчитывать, что поддержку вариантности для классов добавят в следующих версиях языка. Идеи ответа одолжены из ответа Эрика Липперта, разработчика ко- и контравариантности в C#.
Комментариев нет:
Отправить комментарий