advanced20 min

Nullable Reference Types and Null-Conditional/Coalescing Operators

C#'s null-safety feature, plus the `?.` and `??` operators for working with possibly-null values.

What you'll learn

  • Distinguish a nullable reference type (`string?`) from a non-nullable one (`string`)
  • Use `?.` to safely access a member that might be null
  • Use `??` to supply a fallback value when an expression is null

Explanation

In a modern C# project (with nullable reference types enabled, the default for new projects), the compiler tracks nullability as part of a reference type's type: string means "the compiler expects this is never null," while string? means "this may legitimately be null, and code that dereferences it without checking should get a compiler warning." This is purely a compile-time analysis to catch a common class of bug earlier -- it does not add runtime null checks by itself.

The null-conditional operator ?. accesses a member only if the value on its left isn't null, short-circuiting to null instead of throwing if it is: middleName?.Length is null if middleName is null, or the actual length otherwise -- without it, middleName.Length on a null middleName throws a NullReferenceException at run time.

The null-coalescing operator ?? supplies a fallback when the left side is null: nickname ?? "Unknown" evaluates to nickname if it isn't null, or the literal "Unknown" if it is. The two operators combine naturally: person?.Nickname ?? "Unknown" safely navigates a possibly-null person and still gives you a real value either way.

Inside a composite/interpolated string, a genuinely null value formats as an empty string, not the text "null" -- a subtlety worth knowing before you're surprised by a blank spot in printed output instead of an exception or the word "null".

Guided lab

Predict: Null-conditional and null-coalescing operators

C#Not executed
This lab does not run in your browser or on VisaSparkSchools's servers. Read the code, predict what it does, then reveal the real expected output.

Read this program and predict exactly what it prints.

using System;

string? middleName = null;
string? nickname = "Ace";

int? middleLength = middleName?.Length;
int? nicknameLength = nickname?.Length;

Console.WriteLine($"middleLength: {middleLength}");
Console.WriteLine($"nicknameLength: {nicknameLength}");

string displayName = nickname ?? "Unknown";
string displayMiddle = middleName ?? "(none)";

Console.WriteLine($"displayName: {displayName}");
Console.WriteLine($"displayMiddle: {displayMiddle}");

Stuck? Get a hint.

Common mistakes

  • Dereferencing a `string?` directly without `?.` or a null check, risking a `NullReferenceException` at run time that the compiler had already warned about.
  • Assuming `??` and `?.` do the same thing -- `?.` safely navigates a member access, while `??` supplies a fallback value for an already-evaluated possibly-null expression.
  • Expecting a null value inside an interpolated string to print the word "null" -- it actually formats as an empty string.

Knowledge check

Knowledge check

1. What does `string?` (with a question mark) signal, compared to plain `string`?
2. What does `middleName?.Length` evaluate to when `middleName` is null?
3. What does a genuinely null value print as inside an interpolated string like `$"{value}"`?

Takeaway

Use `?.` to safely navigate a possibly-null reference and `??` to supply a fallback value -- and remember a null value inside an interpolated string formats as an empty string, not the word "null".

Summary

Nullable reference types (`string?`) let the compiler warn about unchecked null dereferences at compile time; `?.` safely navigates possibly-null members, `??` supplies a fallback, and null formats as an empty string in interpolation.

References

Your notes

Notes save automatically.

Finished this lesson?

Mark it complete to track your progress and schedule a future review.