Einige Funktionen meines F # -Codes empfangen Werte als Objekt, obwohl die zugrunde liegenden Werte typisiert sind. Wenn der Wert eine diskriminierte Vereinigung ist, ist es nicht möglich, ihn auf seinen F # -Typ zurückzusetzen. Hier ist ein einfaches Beispiel:Unboxing-Werte von diskriminierten F # -Anschlüssen
type Result<'TOk,'TError> =
| Ok of 'TOk
| Error of 'TError
type ResultA = Result<string, int>
let a = Ok "A"
let o = box a
match o with
| :? ResultA -> printfn "match ResultA"
// | :? ResultA.Ok -> printfn "match" // doesn't compile
| _ when o.GetType().DeclaringType = typedefof<ResultA> -> printfn "match via reflection"
| _ -> printfn "no match"
Die Ausgabe von diesem Beispiel ist „Spiel über Reflexion“ wird Resulta nie erreicht, weil der boxed Wert eines anderen CLR-Typs ist - Result.Ok. Da F # diskriminierte Vereinigungsfälle als eigene Typen dargestellt werden, stimmt der eingerahmte Wert nicht mit dem Typ ResultA überein. Darüber hinaus ist es nicht möglich, es mit ResultA.OK abzugleichen, da es sich innerhalb von F # -Code nicht um einen legalen Typ handelt. Die einzige Möglichkeit scheint die manuelle Instanziierung eines Wertes mit Reflektion zu sein, was ineffizient und albern ist, da der Wert bereits instanziiert ist, er ist hier, er kann nur nicht in F # -Code zugegriffen werden, wenn er einmal eingerahmt ist.
Habe ich etwas übersehen? Gibt es eine einfachere Möglichkeit, einen F # diskriminierten Union-Wert aufzuheben?
Danke Fjodor. Tatsächlich funktionierte der erste Vorschlag nicht - die Variable zum richtigen Typ zu machen, führte explizit zum selben Boxentyp und stimmte nicht überein. Aber der zweite funktionierte - Ändern des Mustervergleichsfalles. –
Sie müssen einen Fehler gemacht haben, als Sie die erste Option ausprobiert haben. Es funktioniert. –
Und ich stimme Ihrer Vorsorge voll zu. Leider muss ich mich aufgrund der Besonderheiten der externen Bibliothek mit einigen Boxed-Werten auseinandersetzen. –