What are nullable reference types in C#?

C# Language Features Intermediate 2–3 Yrs3–5 Yrs Conceptual 1 min read

Quick Answer

Nullable reference types (opt-in since C# 8, on by default in new projects) make the compiler track whether a reference can be null. string means “never null”; string? means “might be null”. The compiler warns when you might dereference a null or assign null to a non-nullable reference. It's compile-time analysis only — no runtime change.

Nullable reference types make the compiler reason about null. With the feature on, string means the reference shouldn't be null and string? means it might be, and the compiler warns me if I dereference something that could be null or assign null where I said I wouldn't. It's purely a compile-time thing — no runtime cost and no runtime guarantee — so data coming from JSON or EF can still surprise me, and I still validate at the edges. There's a null-forgiving operator, x!, for the cases where I know better than the analyzer, but I try not to lean on it.

  • Enabled per project (<Nullable>enable</Nullable>) or per file (#nullable enable).
  • string name — the compiler expects it's always assigned non-null; string? middle — you must null-check before use.
  • Warnings like CS8602 (“dereference of a possibly null reference”) guide you to add checks.
  • The null-forgiving operator x! tells the compiler “trust me, it's not null here” — use sparingly.
  • Attributes like [NotNullWhen(true)] express contracts (e.g. TryParse).

It doesn't stop null at run time (data from JSON, EF, or reflection can still be null), so treat it as a strong hint plus defensive checks at boundaries.