В С# следует ли проверять ссылки, переданные методам на null?

Хорошо, несколько месяцев назад я спросил аналогичный вопрос о C и С++, но я уделял больше внимания С# в последнее время из-за всей "Windows" Телефон ".

Итак, в С# следует ли проверять NULL на границах метода? Я думаю, что это отличается от того, как в C и С++, потому что в С# один обычно может определить, действительна ли данная ссылка, - компилятор не позволит кому-либо передавать неинициализированные ссылки, и поэтому единственной возможной ошибкой является то, что она будет равна нулю, Кроме того, существует определенное исключение, определенное внутри .NET Framework для этих вещей, ArgumentNullException, который, как представляется, кодифицирует то, что программисты считают, что они должны получать, когда был принят недопустимый null.

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

Итак... вы должны проверить нулевые параметры в методах С#?

Ответ 1

Да, проверьте их. Предпочтительно использовать Code Contracts, чтобы сообщить вызывающему, что вам требуются ненулевые параметры

void Foo(Bar bar) {
    Contract.Requires(bar != null);
}

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

Если вы не можете использовать Кодовые контракты, используйте предложение охраны

void Foo(Bar bar) {
    Guard.Against<ArgumentNullException>(bar == null);
}

Сбой быстро.

Ответ 2

Я думаю, что лучше бросить ArgumentNullException (или использовать контракт как Джейсон предлагает), если ваш метод не хочет, чтобы конкретный параметр был нулевым. Это гораздо лучший показатель по контракту клиенту, чтобы он не пропускал нуль в первую очередь при вызове вашего метода.

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

Ответ 3

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

Мы реализовали статический класс AssertUtilities, который имеет кучу метода для параметров и проверки состояния. Я считаю, что некоторые люди называют такие классы Guard.

Например:

    public static void ArgumentNotNull(object argument, string argumentName)
    {
        if (argument == null)
            throw new ArgumentNullException(argumentName);
    }

    public static void ArgumentInRange(decimal argument, decimal minValue, decimal maxValue, string argumentName)
    {
        if (argument < minValue || argument > maxValue)
        {
            throw new ArgumentOutOfRangeException(
                argumentName,
                FormatUtilities.Format("Argument out of range: {0}. Must be between {1} and {2}.", argument, minValue, maxValue));
        }
    }

    public static void ArgumentState(bool expression, string argumentName, string formatText, params object[] args)
    {
        if (!expression)
            throw new ArgumentException(FormatUtilities.Format(formatText, args), argumentName);
    }

    public static void ArgumentHasText(string argument, string argumentName)
    {
        ArgumentNotNull(argument, argumentName);
        ArgumentState(argument.Length > 0, argumentName, "Argument cannot be an empty string.");
    }

Ответ 4

Итак... вы должны проверить нулевые параметры в методах С#?

Да, если, конечно, если null разрешено.

Лучшая перспектива: вы всегда должны проверять допустимые значения параметров. Иногда ссылка разрешена как null, иногда int должна быть >= 0, или строка может быть не NullOrWhiteSpace.

Поэтому рекомендуется начинать каждый метод с блока проверки параметров.

Оттуда есть несколько вариантов. Валидация по внутренним/частным методам обычно считается менее критичной, и по соображениям производительности она может быть условной (или даже исключенной).

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

В большинстве проектов будут использоваться некоторые вспомогательные классы для проверки, чтобы минимизировать повторное кодирование внутри методов. Очень хороший, но еще не очень популярный инструментарий - это встроенный класс System.Diagnostics.Contracts. Инструменты Code-Contracts имеют множество настроек, касающихся проверки параметров.