SHARE:

C# 14: Introducing Null-Conditional Assignment

Introduction

Every new C# release brings its share of improvements to how we write safer and more expressive code. Over the last few years, Microsoft has put a lot of focus on null-safety, and C# 14 continues in that direction with a feature that’s easy to overlook at first glance: null-conditional assignment.

If you’ve already used the null-conditional operator (?.) to read values safely, you’ll feel right at home. The twist here is that in C# 14, the operator can finally be used on the left-hand side of an assignment. It’s a small change, but it cleans up a surprising amount of boilerplate.

Let’s walk through what this means in practice.

Before C# 14: The Operator Was Read-Only

In earlier versions of C#, you could write code like this without worrying about null references

var length = customer?.Address?.Street?.Length;

But as soon as you tried to assign something through a nullable path, the compiler pushed back:

track?.Info = new Metadata();                // not allowed
track?.Info?.Duration = TimeSpan.Zero;       // not allowed
playlist?["title"] = "My Mix";               // not allowed

the left-hand side had to be a location the compiler could guarantee would exist. If any segment was null or might be null, the assignment wasn’t permitted. So developers worked around it the old-fashioned way:

if (track != null && track.Info != null)
{
    track.Info.Duration = TimeSpan.FromMinutes(5);
}

It’s safe… but verbose, repetitive, and not very expressive.

What C# 14 Changes

C# 14 lifts the restriction entirely. You can now write:

  • ?. on the left side
  • ?[] on the left side

And the assignment simply:

  • runs if the receiver is non-null
  • is skipped if it’s null

No exception, no warning, no gymnastics.

It’s exactly the same short-circuiting behavior you already know from null-conditional reads, applied this time to writes.

Practical Example: Audio Track Metadata

To illustrate the feature without repeating examples you’ve already seen elsewhere, here’s a small model from an audio library:

In many real systems, metadata might or might not be available depending on how the track was loaded. This makes it an excellent case for null-conditional assignment.

Assigning Through Nullable Paths

1- Updating nested properties

track.Info?.Duration = TimeSpan.FromMinutes(3.5);

If track.Info is null, the line silently does nothing. If it exists, the property is updated. Simple and intuitive!

2- Updating dictionary entries

track.Info?.Tags?["Genre"] = "Jazz";
track.Info?.Tags?["Mood"] = "Calm";

This replaces a lot of boilerplate that used to look like:

if (track.Info?.Tags != null)
{
    track.Info.Tags["Genre"] = "Jazz";
}

Cleaner and easier to read at a glance.

3- Nullable arrays

string[]? comments = null;
comments?[0] = "Great intro!";

The assignment is skipped with zero risk of throwing an exception.

4- Compound Assignments

track.Info?.Tags?["PlayCount"] = 
    (int.TryParse(track.Info?.Tags?["PlayCount"], out var v) ? v + 1 : 1).ToString();

If any segment in the chain is null, the entire update is skipped.

Why This Feature Matters

1- Fewer null checks scattered everywhere

This is probably the biggest win.
Instead of wrapping every assignment in an if, you can write one concise, intentional expression that communicates clearly what you want to do.

2- Better handling of partially populated data

APIs don’t always give you complete object graphs so Lazy-loaded objects don’t always initialize everything eagerly, and sometimes, the absence of metadata is a legitimate state. Null-conditional assignment fits perfectly into this kind of workflow!

3- No need for over-eager initialization

A lot of developers used to “fix” nullability with aggressive initialization:

track.Info ??= new Metadata();
track.Info.Tags ??= new Dictionary<string, string>();

This forces object creation even when nothing ends up being assigned. With null-conditional assignment, you only modify what already exists.

4- Great for data coming from JSON or external sources

Working with partial JSON payloads is common. You can now safely update them without worrying about which nodes exist:

response.Data?.Track?.Info?.Tags?["Bitrate"] = "320kbps";

Conclusion

Null-conditional assignment is one of those C# features that doesn’t look like much on paper, but once you start using it, you wonder how you lived without it. It cuts down on repetitive guard clauses, reduces cognitive load, and makes deep object graphs safer to work with. It’s not flashy, but it’s solid, practical, and fits naturally into C#’s ongoing improvements around null-safety.
A welcome addition for anyone writing real-world applications.

Written by

anthonygiretti

Anthony is a specialist in Web technologies (14 years of experience), in particular Microsoft .NET and learns the Cloud Azure platform. He has received twice the Microsoft MVP award and he is also certified Microsoft MCSD and Azure Fundamentals.