Вывод ковариантности и контравариантности в C # 4.0 - PullRequest
8 голосов
/ 29 апреля 2010

Когда мы определяем наши интерфейсы в C # 4.0, мы можем пометить каждый из общих параметров как in или out. Если мы попытаемся установить общий параметр как out и это приведет к проблеме, компилятор выдаст ошибку, не позволяя нам это сделать.

Вопрос:

Если у компилятора есть способы определить, какие допустимые значения используются для covariance (out) и contravariance (in), почему мы должны отмечать интерфейсы как таковые? Разве не достаточно просто дать нам возможность определить интерфейсы, как мы всегда это делали, и когда мы попытались использовать их в нашем клиентском коде, вызвать ошибку, если мы попытались использовать их небезопасным способом?

Пример:

interface MyInterface<out T> {
    T abracadabra();
}
//works OK

interface MyInterface2<in T> {
    T abracadabra();
}
//compiler raises an error.
//This makes me think that the compiler is cappable 
//of understanding what situations might generate 
//run-time problems and then prohibits them.

Также

разве это не то, что делает Java в такой же ситуации? Из того, что я помню, вы просто делаете что-то вроде

IMyInterface<? extends whatever> myInterface; //covariance
IMyInterface<? super whatever> myInterface2; //contravariance

Или я все смешиваю?

Спасибо

Ответы [ 2 ]

8 голосов
/ 29 апреля 2010

Если у компилятора есть способы определения того, что является допустимым использованием как для ковариации (выход), так и для контравариантности (вход), почему мы должны помечать интерфейсы как таковые?

Я не совсем уверен, что понимаю вопрос. Я думаю, что вы спрашиваете две вещи.

1) Может ли компилятор выводить дисперсионные аннотации?

и

2) Почему C # не поддерживает дисперсию колл-сайта, как в Java?

Ответ на первый вопрос:

interface IRezrov<V, W> 
{
    IRezrov<V, W> Rezrov(IRezrov<W, V> x);
}

Я приглашаю вас попытаться определить, какие все юридически возможные аннотации отклонений есть на V и W. Вы можете получить сюрприз.

Если вы не можете определить уникальную аннотацию наилучшей дисперсии для этого метода, почему, по вашему мнению, компилятор может?

Больше причин здесь:

http://blogs.msdn.com/ericlippert/archive/2007/10/29/covariance-and-contravariance-in-c-part-seven-why-do-we-need-a-syntax-at-all.aspx

В более общем смысле: ваш вопрос указывает на ошибочные рассуждения. Возможность дешевой проверки правильности решения не логически означает, что существует дешевый способ найти правильное решение. Например, компьютер может легко проверить, является ли p * q == r истинным или ложным для двух тысячных простых чисел p и q. Это не означает, что легко взять r и найти p и q такими, что равенство выполнено. Компилятор может легко проверить правильность или неправильность аннотации; это не означает, что он может найти правильную аннотацию отклонений среди потенциально миллиардов возможных аннотаций.

Ответ на второй вопрос: C # не Java.

0 голосов
/ 29 апреля 2010

ОК, вот ответ на мой вопрос (из ответа Эрика): http://blogs.msdn.com/ericlippert/archive/2007/10/29/covariance-and-contravariance-in-c-part-seven-why-do-we-need-a-syntax-at-all.aspx

Во-первых, мне кажется, что разница должно быть то, что вы намеренно вписать в ваш интерфейс или делегат. Делая это просто начать происходить без контроля со стороны пользователь работает против этой цели, а также может внести критические изменения. (Больше на тех, в более позднем посте!)

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...