2016-12-21 1 views
6

Angesichts dieser beiden diskriminierten Gewerkschaften möchte ich die DeclaringType aus einer Fall-Instanz erhalten.Wie erhalten Sie den diskriminierten Unionstyp aus einer Fallinstanz?

type SingleCaseUnion = 
    | One 

type MultiCaseUnion = 
    | Two 
    | Three 

Ein Beispiel für jeden Fall sein würde, wie folgt: war

getDiscriminatedUnionType One = typeof<SingleCaseUnion> // true 

getDiscriminatedUnionType Three = typeof<MultiCaseUnion> // true 

Mein erster Versuch, den Fall Art zu bekommen und es ist Basisklasse zu erhalten, funktioniert dies, weil in F # ein Subtyp für jeden Fall erstellt.

MultiCaseUnion.Two.GetType().BaseType = typeof<MultiCaseUnion> // true 

Für eine einzelne Fall Union funktioniert dies jedoch nicht, da keine verschachtelten Typen erstellt werden.

SingleCaseUnion.One.GetType().BaseType = typeof<SingleCaseUnion> // false 

Mein zweiter Versuch, die eine robustere Lösung zu erhalten Ziel war es, die FSharp Reflection Helfer zu verwenden.

Dies funktioniert für alle Fälle, aber es muss UnionCaseInfo-Instanzen für jeden Fall generieren, die etwas unnötig scheint.

Ist etwas eingebaut, dass ich vielleicht verpasst habe? Etwas wie:

FSharpValue.GetUnionFromCase(SingleCaseUnion.One) 

Antwort

4

Wie wäre es

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 
+0

Es ist wahrscheinlich die beste Lösung im Moment. Es verlangt jedoch nicht, dass der Typ eine diskriminierte Union ist. –

+0

AFAIK, gibt es keine Möglichkeit, zu einem Union-Typ zu beschränken. Als Zusicherung jedoch hinzugefügt. – Asti

Verwandte Themen