Когда проверять нулевые аргументы с включенными обнуляемыми ссылочными типами - PullRequest
0 голосов
/ 05 февраля 2019

Учитывая функцию в программе, использующей функцию обнуляемых ссылочных типов C # 8.0, должен ли я по-прежнему выполнять нулевые проверки аргументов?

void Foo(string s, object o)
{
    if (s == null) throw new ArgumentNullException(nameof(s)); // Do I need these?
    if (o == null) throw new ArgumentNullException(nameof(o));
    ...
}

Ни один из кодов не является частью общедоступного API, поэтомуЯ подозреваю, что эти проверки могут быть излишними.Два параметра не помечены как обнуляемые, поэтому компилятор должен предупредить, если какой-либо вызывающий код может передавать значение null.

1 Ответ

0 голосов
/ 05 февраля 2019

Учитывая функцию в программе, использующую функцию обнуляемых ссылочных типов C # 8.0, должен ли я по-прежнему выполнять нулевые проверки аргументов?

Это зависит от того, насколько вы уверены ввсе пути через ваш API.Рассмотрим этот код:

public void Foo(string x)
{
    FooImpl(x);
}

private void FooImpl(string x)
{
    ...
}

Здесь FooImpl не является частью общедоступного API, но все равно может получить нулевую ссылку, если Foo не проверяет его параметр .(Действительно, для проверки аргументов может потребоваться Foo.)

Регистрация в FooImpl определенно не является избыточной , поскольку она выполняет проверки во время выполнения, что компилятор не может быть абсолютно уверен во время компиляции.Обнуляемые ссылочные типы улучшают общую безопасность и, что более важно, выразительность кода, но они не являются той же безопасностью типов, которую обеспечивает CLR (чтобы вы перестали воспринимать string ссылку как * 1023).* ссылка, например).Существуют различные способы, которыми компилятор может «ошибаться» в своем представлении о том, может ли конкретное выражение быть нулевым во время выполнения, и компилятор может быть переопределен с помощью ! в любом случае.

В более широком смысле:если ваши проверки не были избыточными до C # 8, они не избыточны после C # 8, потому что функция обнуляемого ссылочного типа не изменяет IL, сгенерированный для кода, отличного отс точки зрения атрибутов.

Таким образом, если ваш публичный API выполнял все соответствующие проверки параметров (Foo в приведенном выше примере), то проверка в коде уже была избыточной.Насколько вы уверены в этом?Если вы абсолютно уверены в себе, и влияние ошибки невелико, тогда обязательно - избавьтесь от проверки.Функция C # 8 может помочь вам обрести уверенность в этом, но вы все равно должны быть осторожны, ведь вы не получаете слишком уверенности - в конце концов - приведенный выше код не даст никаких предупреждений.

Лично я не удаляю проверку параметров при обновлении Noda Time для C # 8.

...