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


The analyzer detected a block of code that may lead to raising a NullReferenceException in a class destructor (finalizer) when executed.

The body of a class destructor is a critical spot of the program. Starting with .NET version 2.0, throwing an unhandled exception in the destructor body will cause it to crash. An exception that has left the destructor cannot be handled afterwards.

What follows from this explanation is that when addressing objects inside a destructor, you should test them for null in advance to avoid a crash.

Consider the following example:

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

Since the 'numbers' collection was not initialized at declaration time, the 'numbers' field is not guaranteed to contain the reference to the object of class 'A' when this object is finalized. Therefore, we should additionally test the collection for null or wrap the call to the field into a try/catch block.

A correct version of the code above should look like this:

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

Starting with C# version 6.0, you can use the '?.' operator to reduce the check to the following code:

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

According to Common Weakness Enumeration, potential errors found by using this diagnostic are classified as CWE-476.


Bugs Found

Checked Projects
334
Collected Errors
12 668