V3100. NullReferenceException is possible. Unhandled exceptions in destructor lead to termination of runtime.


Анализатор обнаружил код, который может привести к возникновению исключения NullReferenceException в деструкторе (финализаторе) класса.

Тело деструктора класса является критичным местом в программе. Начиная с версии .NET 2.0, возникновения неперехваченного исключения в теле деструктора приводит к полой остановке программы. Перехватить исключение, выпущенное из деструктора, в дальнейшем невозможно.

Из этого следует, что при обращении к объектам внутри деструктора, следует предварительно проверять их на null во избежание падения.

Рассмотрим пример:

class A
{
  public List<int> numbers { get; set; }
  ~A()
  {
    if (numbers.Count > 0) { 
      ....
    }
  }
}

Т.к. изначально коллекция 'numbers' не была проинициализирована при объявлении, мы не можем утверждать, что при финализации объекта класса 'A', поле 'numbers' будет содержать ссылку на объект. Поэтому, стоит дополнительно проверить коллекцию на null, либо обернуть обращение к полю в блок try/catch.

Безопасный вариант кода может выглядеть следующим образом:

~A()
{
  if (numbers != null)
  {
    if (numbers.Count > 0)
    {
       ....
    }
  }
}

Начиная с версии языка C# 6.0, с помощью оператора '?.', можно сократить проверку до:

~A()
{
  if (numbers?.Count > 0) { 
    ....
  }
}

Согласно Common Weakness Enumeration, потенциальные ошибки, найденные с помощью этой диагностики, классифицируются как CWE-476.


Найденные ошибки

Проверено проектов
346
Собрано ошибок
13 188

А ты совершаешь ошибки в коде?

Проверь с помощью
PVS-Studio

Статический анализ
кода для C, C++, C#
и Java

goto PVS-Studio;