Skip to content

[Proposal]: Nominal Type Unions #9411

Open
@mattwar

Description

@mattwar

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.

LDM Notes

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions