Dev

Union Types Finally Arrive in C# 15 and .NET 11

The long-awaited union types in C# will be implemented in .NET 11 and C# 15. This article explains the new feature that brings powerful functional programming patterns to C#.

5 min read Reviewed & edited by the SINGULISM Editorial Team

Union Types Finally Arrive in C# 15 and .NET 11
Photo by Sai Manne on Unsplash

A Long-Awaited Milestone In the evolution of programming languages, there are moments when the wishes of the developer community are fulfilled. For C#, one of these milestones is the introduction of union types. Long requested by developers, this feature is finally becoming a reality in C# 15 and .NET 11. Available for testing in the preview version of .NET 11, this new feature significantly enhances C#‘s type system, enabling safer and more expressive code.

What Are Union Types? Union types are a fundamental data structure widely used in functional programming. Many functionally-oriented languages, such as F#, TypeScript, and Rust, already support them. At their core, union types embody the concept of “a single type being able to hold one of several different values.” A simple example is types like Option<T> or Result<TSuccess, TError>. Particularly, Result<TSuccess, TError> is easy to understand—it represents the result of an operation that can either succeed or fail. In case of success, it holds a value of type TSuccess, and in case of failure, it contains error information of type TError. This pattern forces the caller to handle both scenarios explicitly, making error handling more robust. However, union types aren’t limited to such common patterns. They can represent combinations of arbitrary and potentially unrelated types, making them especially useful for scenarios where data can take on different forms.

Implementation in C# 15: The union Keyword In traditional C#, expressing the idea that a value can be one of multiple types has been challenging. For instance, consider record types representing Windows, Linux, and macOS, each with distinct properties. Since these types don’t share common values, creating a base class isn’t a viable solution. Storing them in an object type sacrifices type safety. Alternatively, tracking which type is being held using enumerated tag values can be cumbersome. C# 15 introduces the union keyword, directly supporting such scenarios. Here’s an example of how this can be declared: ```csharp

public record Windows(string Version); public record Linux(string Distro, string Version); public record MacOS(string Name, int Version); public union SupportedOS(Windows, Linux, MacOS); ``` With this declaration, the SupportedOS type is guaranteed at the compiler level to hold an instance of either Windows, Linux, or MacOS. Developers can use this union type to handle different kinds of data in a type-safe manner.

Implementation Details and Customization Andrew Lock, the author of the article, explains the feature based on the .NET 11 Preview 4. Though changes may occur before the final release, the current implementation incorporates union types at the language level, ensuring type safety via the compiler. One of the significant aspects of this feature is that developers can implement custom union types. While it remains uncertain whether the standard library will provide generic types like Result<TSuccess, TError>, the introduction of union types as a language feature is expected to facilitate the sharing of community-created implementations.

Impact and Benefits for Programming The introduction of union types brings several key benefits to C# programming practices: 1. Improved Type Safety: Compared to using the object type or manually managing tagged data structures, union types allow the compiler to catch type mismatches and unhandled cases at compile time. This reduces runtime errors and enhances code reliability. 2. Enhanced Expressiveness: Union types enable developers to explicitly declare that data can take multiple forms directly in type definitions. This makes the structure of the data more intuitive for readers of the code. 3. Integration of Functional Programming Patterns: C# has gradually incorporated elements of functional programming, and with union types, patterns like the Result pattern or optional values handling become more natural. This is particularly useful for clean error handling and data transformation pipelines.

Background and Community Reactions Union types have been a long-standing request in the C# user community. Surveys on Stack Overflow and developer forums often highlighted the demand for this feature, especially among developers transitioning from functional programming languages. Its introduction signifies C#‘s evolution as a more mature multi-paradigm language. Within the .NET ecosystem, F# already supports robust union types. Bringing this feature to C# enhances interoperability between the two languages and offers developers greater flexibility in choosing the right language for their project requirements.

Future Outlook Currently, .NET 11 is in its preview stage, and the syntax and functionality of union types may undergo changes before the final release. Developers are encouraged to experiment with the preview version and provide feedback. In the long term, union types are expected to become a standard coding practice in C#. They will likely be a valuable tool for providing clearer contracts in API design and library development. Additionally, developers may find opportunities to incrementally introduce union types into existing codebases and refactor their projects for enhanced type safety and maintainability.

Conclusion The introduction of union types in C# 15 and .NET 11 marks a significant milestone in the language’s evolution. This long-awaited feature elevates C# to a new level of type safety and expressiveness. By bringing the powerful patterns of functional programming to C#, this feature equips developers with tools to write more robust and maintainable code. As the final release approaches, feedback and experimentation from the developer community will play a crucial role in shaping the future of C#.

Frequently Asked Questions

Will C#'s union types affect existing code?
No, union types are a new language feature and do not require changes to existing code. They can be introduced incrementally into existing codebases. However, you will need to update your project's target framework to .NET 11 and use the C# 15 compiler.
How do union types differ from traditional approaches using the `object` type or base classes?
The key difference is type safety. Using the `object` type requires runtime casting, which can lead to type mismatch errors. Approaches using base classes are limited to types with a shared interface. Union types allow you to define at compile time which types can be held, ensuring all cases are handled and enabling safer, clearer code.
Are C# union types the same as functional programming language features?
While the basic concept is similar, the implementation details vary by language. C#'s union types are designed to integrate with its type system and object-oriented features, making the syntax and usage natural for C# developers. While they resemble F#'s discriminated unions, they are specifically tailored for C#.
Source: Lobsters

Comments

← Back to Home