S8969 — Null-forgiving operators should not be redundant

Language
C#
Type
Code smell
Severity
Minor
Tags
redundant

The null-forgiving operator ! tells the compiler "trust me, this expression is not null", suppressing any nullable warning that would otherwise be raised at this position.

When the compiler’s own nullable flow analysis has already narrowed the operand to non-null before the ! is reached (e.g. through a prior != null check, a switch/is pattern, a loop-exit condition, or a [NotNullWhen]-driven out parameter), the operator suppresses nothing. It becomes dead code that only adds noise and can mislead readers into thinking the nullability of the expression is still in doubt at this point.

Why is this an issue?

Every null-forgiving operator is a claim: "I know more about nullability here than the compiler does." When the flow state already proves the operand non-null, that claim is false, and the operator no longer does anything. Once a codebase accumulates operators like this, readers can no longer tell which ! occurrences are load-bearing (suppressing a real, justified warning) and which are leftovers from an earlier version of the code, a refactor, or a copy-paste. This erodes the value of nullable reference types as a tool for reasoning about the code: developers start distrusting every !, including the ones that matter.


#nullable enable

void M(string? a)
{
    if (a != null)
    {
        _ = a!; // Noncompliant: "a" is already proven non-null here
    }
}

How to fix it

Remove the redundant !; the compiler already treats the expression as non-null without it.

Code examples

Noncompliant code example


#nullable enable

void M(string? a)
{
    if (a != null)
    {
        _ = a!; // Noncompliant
    }
}

Compliant solution


#nullable enable

void M(string? a)
{
    if (a != null)
    {
        _ = a;
    }
}

Resources

Documentation

Related rules

↑ Back to top