Nullable Types & Null Operators (??, ?., ??=)

"Missing data" is everywhere in real software — a user with no middle name, a setting that was never configured, a field left blank. In this lesson you'll learn how C# represents the absence of a value with null , how to let value types hold it, and the trio of operators ( ?? , ?. , ??= ) that let you handle null safely without a pile of if checks.

Learn Nullable Types & Null Operators (??, ?., ??=) in our free C# course — a beginner-friendly interactive lesson with worked examples, a practice exercise…

Part of the free C# course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.

Think of a paper form with a box labelled "Middle name". A box with "James" written in it has a value. A box left blank isn't the same as a box with the word "blank" in it — it's empty . That emptiness is null . The danger is asking "how many letters are in the middle name?" when the box is blank — there's nothing to count, and the program crashes ( NullReferenceException ). The null operators are your way of saying "if the box is empty, do this instead" without panicking.

1. What Is null , and Nullable Value Types

Reference types (like string ) have always been able to be null — they're a pointer to an object, and that pointer can point at nothing. Value types like int normally can't, because they store the number directly. Add a ? after the type to make a nullable value type that can hold null , and you gain two helpers: .HasValue and .Value .

2. The Null-Coalescing Operator ??

Read a ?? b as " a, unless a is null — then b ". It's the single most common way to supply a default value, and it works for both nullable reference and nullable value types. You can even chain several together to pick the first thing that isn't null.

Your turn — fill in the two blanks so a missing name and age fall back to sensible defaults.

3. The Null-Conditional Operator ?.

When you access a member like text.Length and text is null , the program throws a NullReferenceException — the most common crash in all of .NET. The ?. operator says "only do this if the thing on the left isn't null; otherwise the whole expression is just null ". Pair it with ?? for the classic "safe access with a default" one-liner.

4. The Null-Coalescing Assignment ??=

x ??= y is shorthand for "if x is null, set it to y ". It's perfect for lazy initialisation — set something up the first time it's needed, and leave it alone after that. It reads cleaner than the equivalent if (x == null) x = y; .

These lines build a safe display name, but they're scrambled. Put them in the correct order so the code compiles and prints Hello, Guest! when raw is null.

The declaration of raw must come before it's used in ?? , and the method braces wrap everything.

99 — x is null, so ?? falls back to the right-hand value.

2 — s isn't null, so s?.Length is 2 and the ?? default is never used.

set — c already has a value, so ??= leaves it untouched.

Real records are full of optional fields. Here all three null operators work together to render a profile safely, no if statements in sight.

Use all three operators together. Read the brief in the comments, build it, and check your output against the example.

Practice quiz

What does the ?? null-coalescing operator do in 'a ?? b'?

  • Returns a, unless a is null — then b
  • Always returns b
  • Throws if a is null
  • Returns true if a is null

Answer: Returns a, unless a is null — then b. ?? supplies a default: it yields a, but falls back to b when a is null.

What is 'int?' equivalent to?

  • A string
  • Nullable<int>
  • An int array
  • A non-nullable int

Answer: Nullable<int>. int? is shorthand for the struct Nullable<int>, adding .HasValue and .Value and allowing null.

What does the ?. null-conditional operator do when the left side is null?

  • Throws NullReferenceException
  • Returns the whole expression as null
  • Returns 0
  • Continues anyway

Answer: Returns the whole expression as null. ?. short-circuits: if the object is null, the expression becomes null instead of throwing.

What does 'x ??= y' do?

  • Always sets x to y
  • Sets x to y only if x is currently null
  • Compares x and y
  • Reads x with a default

Answer: Sets x to y only if x is currently null. ??= is null-coalescing assignment: it assigns y to x only when x is null.

Why can value types like int not normally hold null?

  • They store the number directly, not a pointer to an object
  • They are too large
  • The compiler forbids it for performance
  • They are always nullable

Answer: They store the number directly, not a pointer to an object. Value types store the value directly; add ? (making int?) to let them hold null.

What happens if you call .Value on a nullable that is currently null?

  • Returns 0
  • Returns null
  • Throws InvalidOperationException
  • Returns false

Answer: Throws InvalidOperationException. Calling .Value on a null nullable throws InvalidOperationException; check .HasValue or use ?? instead.

In 'a ?? b ?? c', which value is produced?

  • The last value c always
  • The first non-null value, left to right
  • All three concatenated
  • null

Answer: The first non-null value, left to right. Chained ?? returns the first non-null operand from left to right.

What does '.HasValue' return for 'int? score = null;'?

  • True
  • False
  • 0
  • It throws

Answer: False. A nullable holding null has HasValue == false.

What is the cleanest 'safe access with a default' one-liner for a possibly-null string s?

  • s.Length
  • s?.Length ?? 0
  • s == null ? throw : s.Length
  • s!.Length

Answer: s?.Length ?? 0. Combine ?. with ?? — s?.Length ?? 0 never throws and gives 0 when s is null.

When should you use ?? versus ??=?

  • ?? reads a value with a fallback; ??= assigns a fallback into the variable
  • They are identical
  • ??= reads; ?? assigns
  • Both only work on int

Answer: ?? reads a value with a fallback; ??= assigns a fallback into the variable. Use ?? to read a value with a fallback; use ??= to assign a fallback into the variable only if it is null.