Given these two Discriminated Unions I'd like to get the DeclaringType
from a case instance.
type SingleCaseUnion =
| One
type MultiCaseUnion =
| Two
| Three
An example for each case would be as follows:
getDiscriminatedUnionType One = typeof<SingleCaseUnion> // true
getDiscriminatedUnionType Three = typeof<MultiCaseUnion> // true
My first attempt was to get the case type and get it's base class, this works because in F# a subtype is created for each case.
MultiCaseUnion.Two.GetType().BaseType = typeof<MultiCaseUnion> // true
However, for a single case union this doesn't work because no nested types are created.
SingleCaseUnion.One.GetType().BaseType = typeof<SingleCaseUnion> // false
My second attempt, which aimed to get a more robust solution was to use the FSharp Reflection helpers.
FSharpType.GetUnionCases(unionValue.GetType()).First().DeclaringType
This does work for all cases but it has to generate UnionCaseInfo instances for each case which seems somewhat unnecessary.
Is there Something built in that I may have missed? Something like:
FSharpValue.GetUnionFromCase(SingleCaseUnion.One)
How about
open FSharp.Reflection
type FSharpType =
static member GetUnionType t =
let ownType = t.GetType()
assert FSharpType.IsUnion(ownType)
let baseType = ownType.BaseType
if baseType = typeof<System.Object> then ownType else baseType
Test:
(FSharpType.GetUnionType MultiCaseUnion.Three).Name //MultiCaseUnion
(FSharpType.GetUnionType SingleCaseUnion.One).Name //SingleCaseUnion
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With