Whetstone.
Nullable reference typesThe ? and the compiler's null tracking
Module 4 · Lesson 112 min

The ? and the compiler's null tracking

Fusion sets <Nullable>enable</Nullable> on every project, which turns C# into a world you already know from strictNullChecks. A reference type is non-nullable by default; string cannot be null and the compiler will warn (and here, because warnings are errors, fail the build) if you might assign null to it. To allow null you write string?, exactly like TS string | null.

Nullable annotations, TS on the right in your head
public string FlightNumber { get; set; } = "";   // never null; note the initializer
public string? DecidedByName { get; set; }        // may be null (string | null)
public DateTime? DecidedAtUtc { get; set; }        // nullable value type (Date | null)

The idiomatic null check is is null and is not null, not == null. They read cleanly and can’t be fooled by an overloaded == operator. You’ll see them everywhere in the real code: if (row is null) return null; and x.DecidedAtUtc is not null.

Real null handling from the aggregate repository
var row = await _dbContext.FlightDisruptionCostCalcs
    .AsNoTracking()
    .Where(x => x.Id == snapshotId)
    .FirstOrDefaultAsync();

if (row is null)
{
    return null;   // flow analysis: below here, row is non-null
}

return new FlightSnapshotSummary(row.Id, row.FlightNumber, /* ... */);
Practice

Try it yourself

Do

Trace the compiler's null flow

Confirm the compiler narrows null exactly like TS does.

  • Open persistence/DisruptionDecisions/FlightDisruptionAggregateRepository.cs
  • Find LoadSnapshotById and the if (row is null) return null; guard
  • Note that after the guard, row.Id is accessed with no null check: the compiler knows row is non-null there
  • Confirm the method return type is Task<FlightSnapshotSummary?> because it CAN return null
Done whenYou can point to where null is possible (return type ?), where it's checked (is null guard), and where the compiler treats the value as non-null afterward.
Sign in to track your progress →