C# welcomes union types in November—a catch-up that brings the language closer to F# and Rust

Dev & Code Sep 3, 2026Add to bookmarks

C# welcomes union types in November—a catch-up that brings the language closer to F# and Rust

Microsoft confirms via The Register the arrival of union types in C# in November 2026. A feature that TypeScript, Rust, Swift, and F# have had for a long time, and which changes the way business states are modeled in C#.

The concrete case

How many times have we written this kind of C# code to represent a state that can take three distinct forms?

public class PaymentResult
{
 public bool IsSuccess { get; set; }
 public string? TransactionId { get; set; }
 public bool IsPending { get; set; }
 public string? PendingReason { get; set; }
 public bool IsError { get; set; }
 public string? ErrorCode { get; set; }
 public string? ErrorMessage { get; set; }
}

An object where three booleans mutually exclude each other, five nullable fields that only make sense in combination with a specific boolean, and zero compiler guarantees that we won’t forget a case in the if/else. Welcome to modeling by convention, which relies on developer discipline—i.e., not much.

What's happening

The Register announced on September 2, 2026, that Microsoft has confirmed the arrival of union types—also called "discriminated unions" or "sum types"—in C# in November 2026.

The idea is simple: instead of an object with five fields that "can be a success, pending, or an error," you explicitly declare to the compiler that the type is one of three mutually exclusive cases, each with its own relevant fields.

In pseudo-C# (the final syntax will be officially announced):

public union PaymentResult
{
 Success(string TransactionId);
 Pending(string Reason);
 Error(string Code, string Message);
}

// Usage
switch (result)
{
 case PaymentResult.Success s:
 Console.WriteLine($"Transaction {s.TransactionId}");
 break;
 case PaymentResult.Pending p:
 Console.WriteLine($"Pending: {p.Reason}");
 break;
 case PaymentResult.Error e:
 Console.WriteLine($"Error {e.Code}: {e.Message}");
 break;
 // The compiler will flag if a case is missing
}

The compiler checks the exhaustiveness of the switch: forgetting a case becomes an error, not a production bug discovered six months later.

Why this matters

F#, C#’s functional cousin in the same .NET ecosystem, has had discriminated unions forever—it’s one of the language’s historical selling points. Rust has made them a cornerstone of its design (the famous enum and match). Swift does too. TypeScript, in its own way, has had union types since 2015. Kotlin has sealed classes that approach the pattern. C# was lagging behind—you had to jury-rig abstract class hierarchies, sealed records, or third-party libraries like OneOf<T1,T2,T3>.

Three concrete consequences of this arrival:

  1. Business modeling becomes more honest. Mutually exclusive states that were represented by convention become types. The compiler becomes an ally in not forgetting anything.
  2. Libraries like OneOf and LanguageExt will reorganize. Part of what they offered becomes native; the rest (monads, partial application) remains useful.
  3. The C#/F# boundary blurs even further. F# will retain its strengths (deeper type inference, the |> pipeline, default immutability), but the gap narrows—the question of language choice in a .NET project is now different.

What to check before diving in

  • The final syntax: Microsoft hasn’t published the final spec yet. The examples above are illustrative.
  • Interop: How C# unions serialize to JSON, behave in Entity Framework, or expose themselves in WCF/gRPC. These details will determine their real-world adoption.
  • Compatibility: Unions are likely arriving in C# 14+ with .NET 10. Projects on legacy .NET Framework or .NET 8 LTS will have to wait.

Key takeaway

Union types in C# are F# seeping into C#—the editorial line of Mads Torgersen (C# lead designer) for several versions now. For our projects, the most immediate benefit is modeling API results (success/error/partial), workflow states (draft/in review/published), and polymorphic payloads (event sourcing, Kafka messages).

This isn’t revolutionary—the major languages have had it for 10 years. But for the .NET enterprise ecosystem, where C# remains the dominant language in business logic, it’s a qualitative leap in type safety. Worth testing as soon as the November preview lands.

Resources, try it

Article produced by artificial intelligence, reviewed under human editorial control.

Our newsroom
Your Linux server, as a desktop.
TermalOSSponsored
Ops, reimagined

Your Linux server, as a desktop.

Agentless SSH monitoring, a full remote desktop and an AI ops copilot — no agents to install, everything stays on your machine.

SSHSelf-hostedAI Ops
Get early access
Was this article helpful?

19 people liked this article

Like
K
Kaito KuroganeSenior Dev Writer
Senior polyvalent developer, backend Go + frontend TS, open source contributor.
Share:
Your Linux server, as a desktop.
TermalOSSponsored
Ops, reimagined

Your Linux server, as a desktop.

Agentless SSH monitoring, a full remote desktop and an AI ops copilot — no agents to install, everything stays on your machine.

Get early access
LIVERadio Geek Kitsune
Tap to listen, the same sound for everyone
0··
// Schedule
// all stations
// share a track →
Topics
Explore
Information