Skip to content

[API Proposal]: union #114844

@HughPH

Description

@HughPH

Background and motivation

I apologise if this has already appeared, I don't see an API Proposal for it explicitly (with union in the title)

When dealing with interop with C/C++, and sometimes when porting, there are times when it would be handy to have a union.

API Proposal

union {
    [type1] [nameA];
    [type2] [nameB];
    [type3] [nameC];
}

API Usage

[StructLayout(LayoutKind.Sequential)]
struct MyStruct {
    public int* thingiesHandle; // unrelated

    public int thingiesCount; // unrelated

    internal union {
        int whyAreTheseInTheSameMemory;
        float nobodyKnows;
        Vector2OfShort itsAMystery;
        fixed byte isThisAStretchTooFar[4];
    }
}

Alternative Designs

Behind the scenes it would create an explicitly laid out struct the size of its largest member that would behave like a tuple with access to the fields like Unsafe.As or *(T*)ptr. So in that sense perhaps there are alternatives like Tuple<T1,T2>(val1,val2) vs (val1,val2) or Nullable<T> vs T? maybe something like Union<T1,T2,T3> though that wouldn't work at all with fixed buffers.

The other need would be to be able to inject names, which would probably blow a hole in that:

unsafe struct Union<T1, T2> where T1: unmanaged where T2: unmanaged
{
    private void* _ptr;
    
    public T1 AsT1 => *(T1*)_ptr;
    public T2 AsT2 => *(T2*)_ptr;
}

I'd just want to refer to the aliases by which the same memory goes, rather than myStruct.MyUnion.AsT1 (for example)

Risks

The only fly in the ointment that I can think of is lack of clarity in the IL. You'd be creating a field in the owning struct that has a size, and then just load it as whatever type is being requested just like an unsafe cast. BUT dotnet already produces things with weird names for anonymous types, lambdas, and so forth, and very few people try to understand the code by reading the IL. The performance impact is zero.

Metadata

Metadata

Assignees

No one assigned

    Labels

    api-suggestionEarly API idea and discussion, it is NOT ready for implementationneeds-area-labelAn area label is needed to ensure this gets routed to the appropriate area owners

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions