Зачем нам нужны новые ключевые слова для Ковариации и Контравариантности в C #?

StackOverflow https://stackoverflow.com/questions/268836

Вопрос

Кто-нибудь может объяснить, почему существует необходимость добавить параметр out или in, чтобы указать, что универсальный тип является вариантом Co или Contra в C # 4.0?

Я пытался понять, почему это важно и почему компилятор не может просто разобраться в этом..

Спасибо,

Джош

Это было полезно?

Решение

У Эрика Липперта, который работает над langauge, есть серия постов на msdn, которые должны помочь прояснить связанные с этим проблемы:
http://blogs.msdn.com/ericlippert/archive/tags/Covariance+and+Contravariance/default.aspx

При чтении статей, показанных по этой ссылке, начинайте снизу и продвигайтесь вверх.

В конце концов вы доберетесь до #7 (Зачем нам вообще нужен синтаксис?).

Другие советы

На самом деле мы этого не делаем потребность их, больше, чем нам нужно abstract на занятиях или на обоих out и ref.Они существуют только для того, чтобы мы, как программисты, могли сделать наше намерение предельно ясным, чтобы программист по обслуживанию знал, что мы делаем, а компилятор мог убедиться, что мы делаем это правильно.

Ну, главная проблема заключается в том, что если у вас есть иерархия классов, подобная:

   class Foo { .. } 

   class Bar : Foo { .. } 

И у вас есть IEnumerator<Bar>, вы не можете использовать это как IEnumerator<Foo> даже несмотря на то, что это было бы совершенно безопасно.В 3.5 это вызывает большое количество болезненных вращений.Эта операция всегда была бы безопасной, но запрещена системой типов, поскольку она не знает о ковариантном использовании параметра универсального типа. IEnumerator<Bar> может возвращать только Bar и каждый Bar является Foo.

Аналогично, если бы у вас был IEqualityComparer<Foo> он может быть использован для сравнения любой пары объектов типа Foo даже если один или оба являются Bar, но это не может быть приведено в IEqualityComparer<Bar> потому что он не знает о контравариантном использовании параметра универсального типа. IEqualityComparer<Foo> использует только объекты типа Foo и каждый Bar является Foo.

Без этих ключевых слов мы вынуждены предположить, что общий аргумент может встречаться как в качестве аргумента метода, так и в качестве результирующего типа метода, и поэтому мы не можем безопасно разрешить ни одно из вышеуказанных преобразований.

С ними система типов свободна, позволяя нам безопасно передавать данные вверх и вниз между этими интерфейсами в направлении, указанном ключевым словом, и мы получаем ошибки, указывающие, когда мы нарушаем дисциплину, необходимую для обеспечения такой безопасности.

В in и out ключевые слова были ключевыми словами начиная с C # 1.0 и использовались в контексте in- и out- параметры для методов.

Ковариация и контравариантность - это ограничения на то, как можно реализовать интерфейс.Нет хорошего способа вывести их - я думаю, единственный способ - это использовать, а это было бы беспорядочно и в конце концов не сработало бы.

Джон и Джоэл оба дали довольно полный ответ на этот вопрос, но суть в том, что они не так уж необходимый компилятором, но скорее помогают гарантировать безопасность реализации, явно указывая отклонение параметра.Это следует очень похожей схеме, требующей out или ref ключевое слово как на сайте вызова, так и на сайте объявления.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top