← Debugging Guides

阅读中文版本

C# CS8602 — Dereference of a Possibly Null Reference

Fix CS8602 nullable warnings by adding a real null check, using the null-forgiving operator only with proof, and annotating nullability correctly.

intermediatedebuggingcsharpnullablestatic-analysis

Symptoms

  • Warning CS8602: Dereference of a possibly null reference
  • Warnings appear only after enabling nullable reference types
  • Suppressing one warning moves it to a later line

Possible causes

  • Nullable reference types are enabled and the value may legitimately be null
  • A helper returns a possibly-null value that the caller dereferences
  • A null check exists but the compiler cannot track it across a method boundary

Diagnosis steps

Locate the dereference and its source

dotnet build /p:TreatWarningsAsErrors=true -warnaserror:CS8602

Interpretation

Turning the warning into an error pins the exact line and prevents it from moving.

Inspect the flow analysis

dotnet build -warnaserror 2>&1 | grep CS8602

Interpretation

The warning line shows which value the analyzer believes can be null.

Root cause

With nullable reference types enabled, the compiler tracks null-state flow. CS8602 is reported when a dereference occurs while the analyzer cannot prove the value is non-null on that path.

Fix

Add an explicit null check and return or throw early, use is not null patterns, and reserve the null-forgiving `!` for cases where non-null is guaranteed by construction with a short comment explaining why.

Risk note

Blanket use of the null-forgiving operator turns a compile-time warning into a runtime NullReferenceException.

Verify the fix

Build with warnings as errors and confirm CS8602 is gone; add a unit test passing null and asserting a controlled ArgumentNullException or default.

Symptoms

When you hit “C# CS8602 — Dereference of a Possibly Null Reference”, guessing wastes time. The guide below follows evidence: reproduce the symptom, run targeted diagnostics, identify the root cause, apply the fix, and verify it with concrete checks.

Observed symptoms include:

  • Warning CS8602: Dereference of a possibly null reference
  • Warnings appear only after enabling nullable reference types
  • Suppressing one warning moves it to a later line

Reproduce and Diagnose

Reproduce the failure in isolation before changing any code. Work through the checks below in order; each one narrows the search space.

Step 1: Locate the dereference and its source

dotnet build /p:TreatWarningsAsErrors=true -warnaserror:CS8602

Turning the warning into an error pins the exact line and prevents it from moving.

Step 2: Inspect the flow analysis

dotnet build -warnaserror 2>&1 | grep CS8602

The warning line shows which value the analyzer believes can be null.

Likely contributors, in order of frequency:

  • Nullable reference types are enabled and the value may legitimately be null
  • A helper returns a possibly-null value that the caller dereferences
  • A null check exists but the compiler cannot track it across a method boundary

Root Cause

With nullable reference types enabled, the compiler tracks null-state flow. CS8602 is reported when a dereference occurs while the analyzer cannot prove the value is non-null on that path.

The Fix

Add an explicit null check and return or throw early, use is not null patterns, and reserve the null-forgiving ! for cases where non-null is guaranteed by construction with a short comment explaining why.

Watch out: Blanket use of the null-forgiving operator turns a compile-time warning into a runtime NullReferenceException.

public string Greet(User? user)
{
    if (user is null)
        throw new ArgumentNullException(nameof(user)); // flow: non-null after

    return $"Hello, {user.Name}";
}

// only when non-null is guaranteed by construction
var name = cache["user"]!.Name; // cache seeded above; safe by contract

Verify and Prevent

Build with warnings as errors and confirm CS8602 is gone; add a unit test passing null and asserting a controlled ArgumentNullException or default.

Once verified, add a regression test that reproduces the original symptom so the failure cannot silently return.

This class of failure is usually environmental rather than pure logic, so capture the exact command, the environment variables, and the working directory in your bug report. Reproduce it in the smallest possible script, then widen the scope only once the minimal case is understood. A short written checklist for this failure mode saves hours the next time it appears.