Nano Hash - криптовалюты, майнинг, программирование

Вывод ковариации и контравариантности в C # 4.0

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

Вопрос:

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

Пример:

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

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

Спасибо


Ответы:


1

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

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

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.

29.04.2010
  • Я думаю, что его второй вопрос был больше похож на то, как аннотации вариативности C # отличаются от типов подстановочных знаков Java? 29.04.2010
  • @Gabe: C # поддерживает отклонение сайта объявления. Java делает отклонение от call-site. Разумеется, вариант вызова сайта - интересная идея, но мне кажется странным иметь вариант типа, основанный на том, как он используется на конкретном сайте, а не на том, как он определен для поведения. 29.04.2010
  • Да, теперь я понимаю, в чем проблема с использованием Java. У него есть преимущество в том, что ему не нужно указывать параметры интерфейса как входящие или выходящие, но тогда какой-то клиент может дать ему какое-то применение прямо сейчас, что позже может не быть превзойдено, если я планирую обновить свой интерфейс. 29.04.2010
  • На самом деле, в вашем примере Резрова было бы всего 4 ситуации: V и T могут быть как внутри, так и снаружи (или ничего, но это не в счет). Или я не прав? В любом случае, вам не нужно проверять все ситуации, только те ситуации, которые пытается запустить клиентский код. То есть вы просто что-то проверяете, когда пытаетесь скомпилировать код, который определенным образом использует интерфейс. 29.04.2010
  • ‹В V, вне W› - это хорошо. ‹Out V, in W› тоже хорошо. Какой из них правильный? Теперь предположим, что один вызывающий использует V как ковариантный, а другой - как контравариантный. В каком из них возникает ошибка? Или оба работают? 29.04.2010
  • Моя (первоначальная) идея заключалась не в том, чтобы пытаться определить, входят ли V и W при компиляции кода интерфейса кода, а в том, чтобы компилятор проверял любой клиентский код с помощью интерфейса, если то, что они просили, считается безопасным. 29.04.2010
  • Интересно, что Java и C # имеют такие разные реализации вариативности, что дает влияние Мэдса Торгерсена на них обоих. 29.04.2010
  • @Gabe: На самом деле универсальная дисперсия была разработана и реализована, когда универсальные шаблоны были добавлены в среду CLR в версии 2; мы просто не упомянули об этой функции на языке. Мэдс появился немного позже. Конечно, мы, безусловно, хорошо использовали его опыт, чтобы убедиться, что функция была четко определена, когда мы добавляли ее в C # в v4. 29.04.2010

  • 2

    Хорошо, вот ответ на то, что я спросил (из ответа Эрика): 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

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

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

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

    29.04.2010
    Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

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

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..