Description
Nominal Type Unions for C#
The full proposal for this feature is here:
https://github.com/dotnet/csharplang/blob/main/proposals/nominal-type-unions.md
A general discussion thread has been created here:
#9410
Summary
A type union is a type that can represent a single value from a closed and disjoint set of types declared separately. These types, known as case types in this proposal, are not required to be declared in a hierarchy or share a common base (other than object).
record Cat(...); // the case types
record Dog(...);
record Bird(...);
union Pet(Cat, Dog, Bird); // the type union
Values of a case type can be assigned directly to a variable of a type-union type. However, since type unions can represent values of unrelated types, having a variable of one is similar to having a variable typed as object. Interacting with a type union instance typically first involves testing and accessing its value in the form of one of its case types.
Pet pet = new Dog(...);
...
if (pet is Dog d) {...}
This proposal introduces a first class nominal type union to C# that is fundamentally a struct wrapper around a value. It is declared and used like any other type, yet, it is also treated specially in some situations to help create an illusion that it is the value and not the wrapper.
union Pet(Cat, Dog, Bird);
becomes
readonly struct Pet
{
public Pet(Cat value) {...}
public Pet(Dog value) {...}
public Pet(Bird value) {...}
public object Value => ...;
}
To treat it like its value, certain operations like casting and pattern matching are translated by the compiler to API calls on the type union instance.
if (pet is Dog dog) {...}
becomes
if (pet is { Value: Dog dog }) {...}
The proposal is broken down into a core set of features needed to make nominal type union's viable and an additional assortment of optional features that may improve performance or capability and can be conditionally implemented over time.