0Pricing
C# Academy · Lesson

Null-Conditional & Null-Coalescing Operators

Combine ?., ?[], ?? and ??= to write concise null-safe code without verbose null checks.

Null-Conditional & Null-Coalescing Operators is a free C# Academy lesson on CoddyKit — lesson 3 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the C# Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

Null-Safe Code Patterns

C# provides three dedicated operators to handle null values concisely: the null-conditional (?., ?[]), null-coalescing (??), and null-coalescing assignment (??=). Together they eliminate most verbose null-check boilerplate.

Null-Conditional Operator: ?.

?. short-circuits to null if the left side is null instead of throwing a NullReferenceException. The result type becomes nullable.

User? user = GetUser(id);

// Without ?.:
string? name = null;
if (user != null) name = user.Name;

// With ?.:
string? name2 = user?.Name;

// Chained:
string? city = user?.Address?.City;

// Method call:
string? upper = user?.Name?.ToUpper();

Null-Conditional with Index Accessor: ?[]

?[] is the null-conditional index operator. It safely accesses array or collection elements when the collection itself might be null.

List<string>? tags = product?.Tags;

// Safe index access
string? firstTag = tags?[0];

// Null-conditional LINQ
int? count = tags?.Count;
bool? hasItems = tags?.Any();

// With methods:
string? joined = tags?.FirstOrDefault()?.ToUpper();

Null-Coalescing Operator: ??

?? returns the left operand if it's not null, otherwise returns the right operand (the fallback). It's the concise replacement for x != null ? x : fallback.

string? name = GetName();

// Without ??:
string display = name != null ? name : "Anonymous";

// With ??:
string display2 = name ?? "Anonymous";

// Chaining ?? for multiple fallbacks:
string result = primary ?? secondary ?? tertiary ?? "Default";

// Combining with ?.
string city = user?.Address?.City ?? "Unknown City";

Null-Coalescing Assignment: ??=

??= assigns the right side to the variable only if the variable is currently null. It's perfect for lazy initialization patterns.

// Lazy initialization
private List<string>? _cache;

public List<string> GetCache()
{
    _cache ??= new List<string>(); // only assigns if null
    return _cache;
}

// Equivalent to:
// if (_cache is null) _cache = new List<string>();

// In-place:
string? name = null;
name ??= "Default";
Console.WriteLine(name); // "Default"

Using ?. with Events

The null-conditional operator is the standard thread-safe way to invoke events — it avoids the race condition of separate null-check and invocation.

public event EventHandler<DataEventArgs>? DataReceived;

// Thread-safe event invocation:
DataReceived?.Invoke(this, new DataEventArgs(data));

// This is equivalent to:
var handler = DataReceived;
if (handler != null) handler(this, new DataEventArgs(data));
// (local copy avoids race condition between check and invoke)

Complex Chaining Examples

Combining operators enables clean, readable null-safe navigation through deeply nested object graphs.

var order = GetOrder(id);

// Deeply nested with fallbacks:
string countryCode = order
    ?.Customer
    ?.ShippingAddress
    ?.Country
    ?.Code
    ?? "US";

// Collection safe access:
decimal firstLineTotal = order
    ?.Lines
    ?.FirstOrDefault()
    ?.Total
    ?? 0m;

// Method chain:
string? trackingUpper = order?.TrackingNumber?.ToUpper().Trim();

Null-Conditional in LINQ

The null-conditional operator works seamlessly with LINQ, allowing safe queries on nullable collections or properties.

List<Order>? orders = customer?.Orders;

// Safe LINQ on a nullable collection:
var totalRevenue = orders?.Sum(o => o.Total) ?? 0m;
var pendingCount = orders?.Count(o => o.Status == OrderStatus.Pending) ?? 0;
var latest       = orders?.MaxBy(o => o.PlacedAt)?.Id;

Null Guards with ThrowIfNull

For parameters that must not be null, use ArgumentNullException.ThrowIfNull() (.NET 6+) for concise, descriptive validation at method entry.

public void ProcessOrder(Order order, Customer customer)
{
    ArgumentNullException.ThrowIfNull(order);
    ArgumentNullException.ThrowIfNull(customer);

    // From this point, compiler knows both are non-null
    Console.WriteLine(order.Id);
    Console.WriteLine(customer.Name);
}

// .NET 7+: ArgumentException.ThrowIfNullOrEmpty
void Save(string name)
{
    ArgumentException.ThrowIfNullOrWhiteSpace(name);
    // name is guaranteed non-empty
}

Is Not Null Pattern in Switch

Pattern matching with is not null and is { } provides clean null-check patterns especially in switch expressions.

string Describe(object? obj) => obj switch
{
    null                          => "nothing",
    string s when s.Length == 0  => "empty string",
    string s                      => $"string: {s}",
    int i                         => $"integer: {i}",
    { }                           => $"object: {obj.GetType().Name}"
};

// is not null in if statements:
if (order is not null && order.Customer is { Name: var name })
    Console.WriteLine(name);

Quick Check

What does the expression user?.Name ?? "Anonymous" return when user is null?

Recap: Null-Conditional & Null-Coalescing

Key takeaways:

  • ?.: safe member access — returns null instead of throwing on null receiver
  • ?[]: safe index access on potentially-null collections
  • ??: fallback value when left operand is null
  • ??=: assign only if null — perfect for lazy initialization
  • Chain them: a?.B?.C ?? defaultVal for deep null-safe navigation
  • ArgumentNullException.ThrowIfNull() for parameter validation guards

Frequently asked questions

Is the “Null-Conditional & Null-Coalescing Operators” lesson free?

Yes — the full text of “Null-Conditional & Null-Coalescing Operators” is free to read here on the web, and the C# Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the C# Academy course, upgrade to CoddyKit PRO.

What will I learn in “Null-Conditional & Null-Coalescing Operators”?

Combine ?., ?[], ?? and ??= to write concise null-safe code without verbose null checks. You practise C# Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start C# Academy?

No prior experience is required. C# Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 3 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “Null-Conditional & Null-Coalescing Operators” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this C# Academy lesson?

Yes. Every C# Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. Enabling & Understanding NRT
  2. Annotations: ?, !, MaybeNull & NotNull
  3. Null-Conditional & Null-Coalescing Operators
  4. Migrating a Codebase to NRT
← Back to C# Academy