I propose we add interop support between F# discriminated unions and C#'s upcoming union types / closed hierarchies, enabling exhaustive pattern matching across the language boundary in both directions.
Full design discussion: [https://github.com//discussions/1463]
Why a separate discussion? C# unions is not one feature — it's a broad umbrella of 10 interlinked proposals (type unions, closed hierarchies, closed enums, case declarations, standard unions, target-typed access, inference features, type-value conversion). On the F# side, discriminated unions compile to 7 different IL layouts depending on case count, struct/ref, and attributes — each with different interop characteristics. The resulting matrix of "which C# feature × which F# layout" is too large for a single issue thread. The discussion has per-topic threads so each combination can be discussed independently.
The existing way of approaching this problem in F# is manually calling .Value on C# union types with no exhaustiveness, and C# consumers using .Tag switch + casts on F# DUs with no exhaustiveness.
Scope
This covers F#'s response to the C# union feature family:
Also related: target-typed inference, ctor inference, pattern inference — F# already handles these.
C# umbrella issue · proposals overview · Roslyn test plan (notes "Ping F# as FYI")
Pros and Cons
Advantages: Exhaustive pattern matching across F#/C# boundary. F# stays current with .NET. Natural extension of F#'s existing DU strength.
Disadvantages: Compiler complexity. C# spec still in preview (risk of churn).
Extra information
Estimated cost (XS, S, M, L, XL, XXL): L
Related suggestions:
- #538 — Erased type-tagged anonymous union types
- #1215 — Kotlin-like sealed classes
- #1052 — Safe enums
- #902 — Deconstruct on DUs for C#
- #606 — Typed union cases
Affidavit (please submit!)
Please tick these items by placing a cross in the box:
Please tick all that apply:
I propose we add interop support between F# discriminated unions and C#'s upcoming union types / closed hierarchies, enabling exhaustive pattern matching across the language boundary in both directions.
Full design discussion: [https://github.com//discussions/1463]
The existing way of approaching this problem in F# is manually calling
.Valueon C# union types with no exhaustiveness, and C# consumers using.Tagswitch + casts on F# DUs with no exhaustiveness.Scope
This covers F#'s response to the C# union feature family:
[Union], auto-unwrapValue, exhaustive match[Closed], emit[Closed]on F# DUs[<Closed>]enumsUnion<T1,T2>)Choice<'T1,'T2>open type+ possible F# equivalentAlso related: target-typed inference, ctor inference, pattern inference — F# already handles these.
C# umbrella issue · proposals overview · Roslyn test plan (notes "Ping F# as FYI")
Pros and Cons
Advantages: Exhaustive pattern matching across F#/C# boundary. F# stays current with .NET. Natural extension of F#'s existing DU strength.
Disadvantages: Compiler complexity. C# spec still in preview (risk of churn).
Extra information
Estimated cost (XS, S, M, L, XL, XXL): L
Related suggestions:
Affidavit (please submit!)
Please tick these items by placing a cross in the box:
Please tick all that apply: