## Why is this an issue?

Accessing a null value will always throw a NullReferenceException most likely causing an abrupt program termination.

Such termination might expose sensitive information that a malicious third party could exploit to, for instance, bypass security measures.

### Exceptions

In the following cases, the rule does not raise:

#### Extensions Methods

Calls to extension methods can still operate on `null` values.

    using System;
    using System.Text.RegularExpressions;

    public static class Program
    {
        public static string RemoveVowels(this string value)
        {
            if (value == null)
            {
                return null;
            }
            return Regex.Replace(value, "[aeoui]*","", RegexOptions.IgnoreCase);
        }

        public static void Main()
        {
            Console.WriteLine(((string?)null).RemoveVowels());  // Compliant: 'RemoveVowels' is an extension method
        }
    }

#### Unreachable code

Unreachable code is not executed, thus `null` values will never be accessed.

    public void Method()
    {
        object o = null;
        if (false)
        {
            o.ToString();    // Compliant: code is unreachable
        }
    }

#### Validated value by analysis attributes

Nullable analysis attributes enable the developer to annotate methods with information about the null-state of its arguments. Thus, potential `null` values validated by one of the following attributes will not raise:

- NotNullAttribute
- NotNullWhenAttribute
- DoesNotReturnAttribute
- DoesNotReturnIfAttribute

It is important to note those attributes are only available starting .NET Core 3. As a workaround, it is possible to define those attributes manually in a custom class:

    using System;

    public sealed class NotNullAttribute : Attribute { } // The alternative name 'ValidatedNotNullAttribute' is also supported

    public static class Guard
    {
        public static void NotNull<T>([NotNull] T value, string name) where T : class
        {
            if (value == null)
            {
                throw new ArgumentNullException(name);
            }
        }
    }

    public static class Utils
    {
        public static string Normalize(string value)
        {
            Guard.NotNull(value, nameof(value)); // Will throw if value is null
            return value.ToUpper(); // Compliant: value is known to be not null here.
        }
    }

#### Validated value by Debug.Assert

A value validated with Debug.Assert to not be `null` is safe to access.

    using System.Diagnostics;

    public void Method(object myObject)
    {
        Debug.Assert(myObject != null);
        myObject.ToString(); // Compliant: 'myObject' is known to be not null here.
    }

#### Validated value by IDE-specific attributes

Like with null-analysis-attribute, potential `null` values validated by one of the following IDE-specific attributes will not raise

##### Visual Studio

- ValidatedNotNullAttribute (The attribute is interpreted the same as the NotNullAttribute)

##### JetBrains Rider

- NotNullAttribute
- TerminatesProgramAttribute

      using System;
      using JetBrains.Annotations;

      public class Utils
      {
          [TerminatesProgram]
          public void TerminateProgram()
          {
              Environment.FailFast("A catastrophic failure has occurred.")
          }

          public void TerminatesProgramIsRespected()
          {
              object myObject = null;
              TerminateProgram();
              myObject.ToString(); // Compliant: unreachable
          }
      }

#### Null forgiving operator

Expression marked with the null forgiving operator

    public void Method()
    {
        object o = null;
        o!.ToString();    // Compliant: the null forgiving operator suppresses the nullable warning
    }

## How to fix it

To fix the issue, the access of the `null` value needs to be prevented by either:

- ensuring the variable has a value, or
- by checking if the value is not `null`

### Code examples

#### Noncompliant code example

The variable `myObject` is equal to `null`, meaning it has no value:

    public void Method()
    {
        object myObject = null;
        Console.WriteLine(o.ToString()); // Noncompliant: 'myObject' is always null
    }

The parameter `input` might be `null` as suggested by the `if` condition:

    public void Method(object input)
    {
        if (input is null)
        {
            // ...
        }
        Console.WriteLine(input.ToString()); // Noncompliant: the if condition suggests 'input' might be null
    }

#### Compliant solution

Ensuring the variable `myObject` has a value resolves the issue:

    public void Method()
    {
        var myObject = new object();
        Console.WriteLine(myObject.ToString()); // Compliant: 'myObject' is not null
    }

Preventing the non-compliant code to be executed by returning early:

    public void Method(object input)
    {
        if (input is null)
        {
            return;
        }
        Console.WriteLine(input.ToString()); // Compliant: if 'input' is null, this is unreachable
    }

## Resources

### Documentation

- CVE - CWE-476 - NULL Pointer Dereference
- Microsoft Learn - NullReferenceException Class
- Microsoft Learn - Attributes for null-state static analysis interpreted by the C# compiler
  - Microsoft Learn - NotNullAttribute Class
  - Microsoft Learn - NotNullWhenAttribute Class
  - Microsoft Learn - DoesNotReturnAttribute Class
  - Microsoft Learn - DoesNotReturnIfAttribute Class
- Microsoft Learn - ValidatedNotNullAttribute Class in Visual Studio
- JetBrains Resharper - NotNullAttribute
- JetBrains Resharper - TerminatesProgramAttribute
- Microsoft Learn - null (C# Reference)
- Microsoft Learn - ! (null-forgiving) operator (C# reference)