Skip to Content
Course content

42: The Null-Conditional and Null-Coalescing Operators

Click on the "Edit" button in the top corner of the screen to edit your slide content.

I want to show you a piece of code that looks perfectly innocent but is actually a landmine. I see this all the time in PRs from developers who are rushing. Imagine we're building a user profile system where users can optionally provide an address.

public class User {
    public string Name { get; set; }
    public Address HomeAddress { get; set; }
}

public class Address {
    public string City { get; set; }
}

// ... somewhere in the logic ...
User user = GetUserFromDatabase(userId);
string city = user.HomeAddress.City; 
Console.WriteLine($"User lives in {city}");

The Dreaded NullReferenceException Chain

The problem here is that we're making two massive assumptions: first, that user isn't null, and second, that the user actually has a HomeAddress object assigned. If the user exists but hasn't filled out their address yet, user.HomeAddress is null. The moment you try to access .City on a null object, the runtime throws a NullReferenceException and your app crashes.

Now, you could fix this the "old way" with nested if-statements. I call this the "Pyramid of Doom" because your code starts drifting further and further to the right of the screen:

string city = "Unknown";
if (user != null) {
    if (user.HomeAddress != null) {
        if (user.HomeAddress.City != null) {
            city = user.HomeAddress.City;
        }
    }
}

It works, but it's exhausting to read and write. It obscures the actual intent of the code—which is simply to get a city name or a default value if it's missing.

Short-Circuiting with the Null-Conditional Operator

This is where the null-conditional operator (?.) becomes your best friend. Think of it as a "safety check" that you can bake directly into your property access. Instead of a full if block, you just swap the dot for a question mark-dot.

// This says: "If the thing to the left is null, stop here and just return null."
string city = user?.HomeAddress?.City;

If user is null, the whole expression evaluates to null immediately. If user exists but HomeAddress is null, it also evaluates to null. It effectively "short-circuits" the chain. I love this operator because it turns five lines of boilerplate into one readable line.

Providing Defaults with Null-Coalescing

The problem now is that city is a nullable string. Often, you don't want a null value passing through your UI; you want a sensible default like "Unknown" or "Not Provided". That's where the null-coalescing operator (??) comes in.

The ?? operator says: "If the value on my left is null, use the value on my right instead." Let's combine it with the conditional operator we just learned:

string city = user?.HomeAddress?.City ?? "Unknown";

Read this as a sentence: "Try to get the city from the user's home address, but if any part of that chain is null, just give me 'Unknown'." It's clean, it's safe, and it's exactly how you should be handling optional data in modern C#.

As a side note, you might also run into the null-coalescing assignment operator (??=). This is a shorthand for assigning a value to a variable only if that variable is currently null. It's great for "lazy loading" or initializing settings:

// Only assign the default list if _cachedUsers is actually null
_cachedUsers ??= LoadUsersFromDatabase();



📋 Practical Task

Building a Robust Application Settings Loader

You are tasked with creating a configuration handler for a game. The game has a GameSettings class and a VideoSettings class. Not all users have customized their video settings; many leave them as null to use the system defaults.

Your Goal: Write a method that retrieves the Resolution string. If the GameSettings object is null, or the VideoSettings object is null, or the Resolution itself is null, the method should return the string "1920x1080".

Requirements:

  • Use the null-conditional operator (?.) to navigate the object hierarchy.
  • Use the null-coalescing operator (??) to provide the fallback resolution.
  • Do not use if statements or ternary operators (? :).
public class VideoSettings {
    public string Resolution { get; set; }
}

public class GameSettings {
    public VideoSettings Video { get; set; }
}

public class SettingsManager {
    public string GetResolution(GameSettings settings) {
        // Your code here
    }
}
Rating
0 0

There are no comments for now.

to be the first to leave a comment.