В C # следует ли проверять ссылки, передаваемые методам, на нуль? - PullRequest
11 голосов
/ 07 мая 2011

Ну, несколько месяцев назад я задал аналогичный вопрос о C и C ++ , но в последнее время я уделяю больше внимания C # из-за всей проблемы с Windows Phone.

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

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

Ответы [ 4 ]

8 голосов
/ 07 мая 2011

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

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

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

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

Fail fast.

5 голосов
/ 07 мая 2011

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

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

3 голосов
/ 07 мая 2011

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

Мы реализовали статический класс 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.");
    }
2 голосов
/ 07 мая 2011

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

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

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

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

С этого момента есть несколько вариантов. Проверка на внутренние / частные методы обычно считается менее критичной, и по соображениям производительности ее можно сделать условной (или даже пропустить).

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

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

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