Как применить проверку на ноль? - PullRequest
14 голосов
/ 26 февраля 2010

Я работаю над большим проектом, в котором, даже с 10 тысячами автоматических тестов и 100% охватом кода, мы получаем смешное количество ошибок. Около 95% ошибок, которые мы получаем, являются NullReferenceExceptions.

Есть ли способ принудительной проверки нуля во время компиляции?

Кроме этого, есть ли какой-нибудь способ автоматически применить нулевую проверку в модульных тестах без необходимости писать тесты для нулевых случаев самостоятельно?

Ответы [ 13 ]

18 голосов
/ 26 февраля 2010

Вы должны изучить Кодовые контракты . Статическая проверка доступна только для более мощных версий VS, но это то, что вам нужно.

Есть много ресурсов в сети, и <plug> вы также можете прочитать предварительную версию главы о контрактах из 2-го издания C # in Depth - скачать главу 15 бесплатно . </plug> (Эта глава немного устарела в отношении последней и лучшей сборки Контрактов кода, но ничего особенного.)

4 голосов
/ 26 февраля 2010

100% покрытие кода ничего не значит.

Это ложное чувство безопасности.

Единственное, что вы измеряете, это то, что вы выполняете все строки кода.

Не

  • То, что эти строки кода - это все строки кода, которые должны были быть там
  • То, что эти строки кода работают правильно (вы тестируете все крайние случаи?)

Например, если ваша процедура борьбы с пожаром содержит 1 шаг «выбег из здания», то, даже если это происходит в 100% случаев, возможно, лучшей процедурой будет «оповещение пожарной охраны, попытаться остановить огонь, а затем бежать, если ничего не помогает ".

Нет ничего встроенного в C #, что поможет вам в этом, если вы не будете специально заходить и добавлять код, либо контракты кода (.NET 4.0), либо специальные операторы IF (<4.0).

1 голос
/ 02 мая 2019

C # 8 ввел Необнуляемые ссылочные типы .

Проект .Net можно изменить, чтобы включить параметр Nullable :

<LangVersion>8.0</LangVersion>
<Nullable>enable</Nullable>

Компилятор сможет различить

  • string и string?

  • NonNullableClass и NullableClass?

1 голос
/ 26 февраля 2010

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

1 голос
/ 26 февраля 2010

1) Я думаю, Resharper может предложить вам проверить некоторые критические места в вашем коде. Например, он предлагает добавить [код проверки нулевой ссылки] и добавляет его, если вы разрешите.

Попробуй. Конечно, это увеличит ваш опыт, если вам нужно.

2) Использование шаблона «Fail Fast» (или утверждение, утверждение) в вашем коде на ранней стадии разработки приложения

1 голос
/ 26 февраля 2010

Есть ли способ принудительной проверки нуля во время компиляции?

Нет. Компилятор не может определить, указывает ли указатель на переменную времени выполнения на ноль.

И исключение нулевых производящих операторов (наборов и возвращений) также недостаточно. Рассмотрим:

public class Customer
{
  public List<Order> Orders {get;set;}
}
  //now to use it
Customer c = new Customer;
Order o = c.Orders.First(); //oops, null ref exception;
1 голос
/ 26 февраля 2010

Это не техническое решение, а социальное.Просто сделайте недопустимым в вашей среде доступ к ссылочному типу без проверки на нулевое значение, если ссылочный тип был каким-либо образом изменен внешним кодом (вызов другого метода и т. Д.).Модульное тестирование не заменяет старый добрый обзор кода.

0 голосов
/ 26 февраля 2010

Проверьте Жандарм , он может быть запущен после сборки вместе с вашими тестами (возможно, до них, если хотите) и имеет несколько правил, касающихся проверок null. Вы также можете довольно просто написать свой собственный.

0 голосов
/ 26 февраля 2010

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

0 голосов
/ 26 февраля 2010

.NET Framework ищет принудительную проверку нулевых ссылок времени компиляции с помощью! Модификатор.

public void MyMethod(!string cannotBeNull)

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

public class ExternalFacing
{
  public void MyMethod(string arg)
  {
     if (String.IsNullOrEmpty(arg))
        throw new ArgumentNullException(arg);

     implementationDependency.DoSomething(arg);
   }
}

internal class InternalClass
{
    public void DoSomething(string arg)
    {
         // shouldn't have to enforce null here.
    }
}

Затем примените соответствующие модульные тесты к классу External, чтобы ожидать ArgumentNullExceptions.

...