Допускает ли возникновение исключений NullReferenceException исключение? - PullRequest
1 голос
/ 17 марта 2011

Я играю с Пексом и Моулзом, и после запуска Пекс обнаружил, что почти все тесты, которые, по словам Пекс, провалились, были вызваны тем, что исключения NullReferenceException были «разрешены».Читая документацию Pex, я наткнулся на следующее:

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

Итак, вышеизложенное говорит о том, что мы должны проверять наличие нулей до того, как другие методы / классы будут вызваны с использованием чего-то вроде:

if(foo == null)
   throw new ArgumentNullException("its null and this shouldn't happen")
else
   Bar(foo); //won't get a null reference exception here because we checked first...

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

Ответы [ 4 ]

9 голосов
/ 17 марта 2011

Да, вы должны проверить свои аргументы перед их использованием, IMO.

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

ArgumentNullException указывает на ошибку в методе ранее в стеке вызовов, чем метод, бросающий его.(Обычно, но не всегда, прямой вызывающий.)

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

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

3 голосов
/ 17 марта 2011

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

1 голос
/ 19 мая 2011

Даже с простой диагностической точки зрения, что вы можете получить больше информации - A NullReferenceException или ArguementNullException ?

Сделайте еще один шаг итрассировка стека из картинки.Возможно, у вас два сообщения:

NullReferenceException:"Ссылка на объект не установлена ​​для экземпляра объекта."

  • Что-то равно нулю, где-то, и я, вероятно,не ожидал, что это будет.
  • Возможно, мне нужно отладить, чтобы найти ошибку.

ArguementNullException:"System.ArgumentNullException: MyVariable не может быть нулевым."

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

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

throw new ArgumentNullException("its null and this shouldn't happen");

Это не правильно.

throw new ArgumentNullException("VariableName");

Это верно.

1 голос
/ 17 марта 2011

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

Самая раздражающая проверка NULL - это строки.Они могут быть довольно неприятными, но я использую метод расширения, чтобы преодолеть это:

public static class StringExtensions
{
    public static string NullSafe(this string s)
    {
        return s ?? string.Empty;
    }
}

Так что вы можете использовать:

myString.NullSafe().ToUpper()
...