NDepend Blog

Improve your .NET code quality with NDepend

C# 15 Unions

August 25, 2025 5 minutes read

C# Unions

In an August 2025 video, Mads Torgersen -lead designer for the C# Programming Language- outlined the C# team’s plans for C# unions. The team aims at potentially introduce this feature with the C# 15 release in November 2026. This is not a commitment but rather a possibility—one that seems quite likely, given how straightforward the plan appears to be. The video is here and he talks about union from 1:02:25 till 1:10:30.

C# Unions Plan

Mads introduces this code to illustrate their plans for unions:

This code feels very idiomatic to C#. Here are some remarks:

  • The type Pet is defined as a union of the existing types Dog, Cat, and Bird. Once declared, there’s no need to repeatedly specify the constituent types—Pet fully encapsulates that definition.
  • The first line, Pet pet = new Dog("Rover"); means that the compiler will know somehow there is an implicit conversion from Dog to Pet, since Pet is not a base class for Dog.
  • Unlike some languages such as F#, the types that make up a union in C# must be defined separately from the union itself. For comparison, in F# a union can be declared as follows, where Car, Truck, and Bicycle are part of the Vehicle union. They can be seen as tags to represent the various cases, instead of being seen as type. This is why, in functional languages, they are called discriminated union or tag union, whereas in the approach chosen by the C# team, it is closer to a structural union or type union.

  • A key benefit is how exhaustiveness checking works with pattern matching in the switch clause. Since the compiler knows that Pet can only ever be a Dog, Cat, or Bird, a switch expression over Pet will not produce warnings once all cases are handled.
  • If we later extend the union by adding, for example, Shark, the compiler will warn (or error?) every switch on Pet that doesn’t account for the new case. This makes Pet a closed union type: its set of possibilities is fixed and enforced by the compiler. This is in contrast to class inheritance, where new subclasses can be introduced without breaking existing code thanks to polymorphism applied on virtual members. This is the Open-Close Principle (OCP): open for extension, closed for modification. In a word OCP applies to class inheritance but not to unions.

C# Union Plan Behind the Scene

The C# team proposes implementing union types as a record struct with a single read-only object? Value property. This design is both simple and powerful, since in C# virtually any type can be represented as an object reference: class, struct, interface, delegate, enumeration,  primitive types… but not unmanaged pointers for example.

Could C# Unions be Smart for Value Type Only Unions?

The trade-off is that value types included in the union, such as Cat, will be boxed when stored in the Value property. The object used to box the value must then be managed by the garbage collector, introducing a small performance overhead.

A more sophisticated implementation of unions could optimize storage for value types that share the same memory footprint (i.e., represented by the same number of bytes). Alternatively, the runtime could allocate space based on the largest value type in the union, with smaller types incurring padding overhead. However, either approach would significantly complicate the implementation. At 1:08:20 Mads explains that the C# Team will provide a way to manually define the layout of your value type only union.

I wish this could be transparently improved. A method  T ValueAs<T>() where T : struct could be added to Pet. In the same vein C# 13 eliminated object allocations for params collections. I believe that unions composed solely of value types are likely to be a common scenario, like for example parser implementation or messaging protocol.

Let’s mention that modern C# and MemoryMarshal makes it easy to cast a range of byte into any value type instance:

Pattern Matching switch over C# Union

Based on the C# team’s plan, enabling pattern-matching switch on a C# union is straightforward. A call to the Value property must be inferred by the compiler.

Conclusion

Again, Mads did not promise that unions will be part of C# 15 in November 2026. He explained that work will begin once C# 14 reaches general availability in November 2025 and hopefully they will make it.

Also he mentioned that they will collaborate with the .NET Core Base Class Library team so that many union types will already be available when this language feature is released

At the end of the talk, someone asked about interoperability between F# unions and C# unions. Since they are fundamentally different (see the explanation above on F# discriminated unions vs. C# type unions), the interoperability model is not straightforward. Nevertheless the team plans to work on it. Mads also added that they might allow defining the types that make up a C# union directly within the union’s scope, similar to F#.

In 2024 we already wrote a blog post named C# Discriminated Union to explain in details the concept to C# developers: C# Discriminated Union: What’s Driving the C# Community’s Inquiries?. Hopefully, things are becoming clearer, and we will update this post with the latest progress from the C# team on this topic.


This article is provided by the team behind NDepend. Whether you are maintaining a large legacy .NET project or starting a new C# application, NDepend helps improve maintainability, security, and code quality. A free full-featured trial is available here for evaluation.

Leave a Reply

Your email address will not be published. Required fields are marked *