Контракты на кодекс в .NET 4.0, не радует фанатов ненулевых ссылочных типов? - PullRequest
9 голосов
/ 01 октября 2009

Я играл с Code Contracts на VS2008 (http://msdn.microsoft.com/en-us/devlabs/dd491992.aspx).
Они, безусловно, хороши и обеспечивают надежную альтернативу проверкам if-then-throw внутри методов.

Тем не менее, я надеялся, что они могут удовлетворить потребность, которую я настоятельно чувствую в необнуляемых ссылочных типах.
Увы, из того, что я мог видеть, похоже, что это не так.
Вот что я понял:

  • Что-то подобное по-прежнему будет вызывать проблемы во время выполнения:
    MyClass a = null;<br> a.ToString();

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

  • Если вы не используете VS Team System, вы можете использовать только контракты кода для проверки во время выполнения, никаких преимуществ во время компиляции.
    Это означает, что вам все равно придется обращаться с вещами, когда что-то идет не так.
    Не сильно отличается от обработки простого исключения.

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

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

Не поймите меня неправильно, мне не нравятся кодовые контракты.
Они являются очень хорошим дополнением ко всему каркасу.
Просто если это не заполнит пробел, который C # оставляет из-за отсутствия необнуляемых ссылочных типов, на данный момент я боюсь, что ничего не выйдет.
Что ты думаешь?

Ответы [ 5 ]

20 голосов
/ 04 октября 2009

Я думаю, вы правы по этому поводу. Необнуляемая проверка ссылок во время компиляции была убийственной функцией, которую я ждал в Code Contracts, и на самом деле ее там нет.

Если вам интересно, что это значит, рассмотрите аналогию с типами значений. Изначально они не были обнуляемыми, но теперь, если вы поставите знак вопроса после имени типа:

int? n;

Для согласованности было бы идеально, если бы то же самое было верно для ссылочных типов. Но это сломало бы все существующие программы C # и поэтому не вариант. На языке исследования Spec # они использовали суффикс восклицательного знака для обозначения ненулевого значения:

string! s = "Hello";

Как и в случае с обычными типами значений, компилятор статически проверяет, что переменная string! не используется ни в каком пути кода до его инициализации (я считаю, что Spec # требует, чтобы объявление и инициализация происходили в одном выражении).

Он также запрещает присвоение null этой переменной.

И, конечно, он запрещает присвоение обычного string string!. Так как же преодолеть разрыв между двумя типами? Выписав чек:

string x = GetStringFromSomewhere();

if (x != null)
    s = x; // okay because compiler sees null check

Печальная правда в том, что большинство ссылочных переменных в большинстве программ, вероятно, не обнуляются, если программа верна. Обнуляемые переменные находятся в меньшинстве. И все же они по умолчанию.

Еще одна плохая идея 1960-х годов !

3 голосов
/ 19 августа 2010

Я думаю, что концепция ненулевого ссылочного типа была бы действительно полезна для сгенерированных ORM свойств, которые сопоставляются с полями базы данных. Часто из свойства (обычно типа string) вы не можете определить, является ли базовое поле обнуляемым или нет. С обнуляемыми типами значений вы можете просто найти знак вопроса.

Меня не слишком беспокоит статическая проверка, кроме явного фу! = ноль; не удалось, но intellisense был бы очень полезен как подсказка для переменной переменной, я думаю.

3 голосов
/ 01 октября 2009

Я не уверен, какую проблему решают "ненулевые ссылочные типы". Итак, этот код с меньшей вероятностью выдает исключение: -

a.ToString();

Однако более ли вероятно, что оно будет правильным , потому что оно не может быть обнулено? Каково будет начальное значение a? Вероятно, какой-то «пустой» экземпляр по умолчанию типа. В этом случае не будет более вероятным затруднить отладку, поскольку значения, которые должны были быть присвоены, не имеют. Просто иметь поведение по умолчанию, а не вызывать исключение, не похоже на то, что я хотел бы.

0 голосов
/ 17 ноября 2017

Необнуляемая проверка ссылок во время компиляции была убийственной функцией, которую я ждал в Code Contracts, и на самом деле ее там нет.

Обновление 2017 года (8 лет спустя), в то время как необнуляемый ссылочный тип все еще не существует ... возможно, обнуляемый ссылочный тип.

Мадс Торгерсен (C # Language PM в Microsoft) упоминает об этом в этом твите :

Прототип обнуляемых ссылочных типов, наконец, здесь!

Это подробно описано в " Представление ссылочных типов, допускающих обнуляемость, в C # " и в этом видео " доступны новые функции C # 7.1 и 7.2 ".

Этого можно достичь, если вместо этого мы добавим только один новый «безопасный» тип ссылочного типа, а затем переосмыслим существующие ссылочные типы как другой «безопасный» тип. В частности, мы считаем, что значение по умолчанию для аннотированных ссылочных типов, таких как строка, должно быть ссылочными типами, не допускающими значения NULL , по нескольким причинам:

Мы считаем, что более распространенным является требование, чтобы ссылка не была нулевой. Вспомогательные ссылочные типы были бы более редкими (хотя у нас нет хороших данных, чтобы сообщить нам, сколько), поэтому именно они должны требовать новой аннотации. В языке уже есть понятие и синтаксис для типов значений, допускающих значение NULL. Аналогия между ними сделает концептуальное добавление языка проще и лингвистически проще.
Кажется правильным, что вы не должны обременять себя или своего потребителя громоздкими нулевыми значениями, если вы активно не решили, что хотите их. Нулевые значения, а не их отсутствие, должны быть предметом, на который вы явно должны согласиться.
Вот как это выглядит:

class Person
{
    public string FirstName;   // Not null
    public string? MiddleName; // May be null
    public string LastName;    // Not null
}

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

Таким образом, мы получаем причину, по которой мы называем эту языковую функцию «ссылочными типами, допускающими обнуление»: это те, которые добавляются в язык. Необнуляемые уже есть, по крайней мере, синтаксически.

Это все еще прототип , и может оказаться (или нет) на языке.
См. Больше в " Предварительный просмотр типов ссылок N # * C # *.

0 голосов
/ 02 ноября 2009

вместо использования нуля вы можете использовать значение по умолчанию, например string.empty, нуля не требуется

...