C # und F # Gießen - speziell die ‚als‘ Schlüsselwort
Frage
In C # kann ich tun:
var castValue = inputValue as Type1
In F #, was ich tun kann:
let staticValue = inputValue :> Type1
let dynamicValue = inputValue :?> Type1
Aber keiner von ihnen ist das Äquivalent der C # 's Schlüsselwort as
.
Ich glaube, ich brauche ein Spiel Ausdruck für das Äquivalent in F # tun
match inputValue with
| :? Type1 as type1Value -> type1Value
| _ -> null
Ist das richtig?
Lösung
Soweit ich weiß, F # hat keine eingebauten Operator entspricht C # as
, so dass Sie etwas mehr kompliziert Ausdruck schreiben müssen. Alternativ zu Ihren Code mit match
, könnten Sie auch if
verwenden, da der Bediener :?
kann Gebrauch in der gleichen Weise wie is
in C # sein:
let res = if (inputValue :? Type1) then inputValue :?> Type1 else null
Sie können eine Funktion natürlich schreiben, dieses Verhalten zu kapseln (durch eine einfache generische Funktion zu schreiben, die ein Object
und Abgüsse es auf den angegebenen generischen Typparameter nimmt):
let castAs<'T when 'T : null> (o:obj) =
match o with
| :? 'T as res -> res
| _ -> null
Diese Implementierung kehrt null
, so erfordert es, dass der Typ-Parameter null
als einen richtigen Wert hat (alternativ könnten Sie Unchecked.defaultof<'T>
, die default(T)
in C # entspricht). Jetzt können Sie einfach schreiben:
let res = castAs<Type1>(inputValue)
Andere Tipps
würde ich ein aktives Muster verwenden. Hier ist diejenige, die ich verwende:
let (|As|_|) (p:'T) : 'U option =
let p = p :> obj
if p :? 'U then Some (p :?> 'U) else None
Hier ist ein Beispiel Verwendung von As
:
let handleType x =
match x with
| As (x:int) -> printfn "is integer: %d" x
| As (s:string) -> printfn "is string: %s" s
| _ -> printfn "Is neither integer nor string"
// test 'handleType'
handleType 1
handleType "tahir"
handleType 2.
let stringAsObj = "tahir" :> obj
handleType stringAsObj
Sie können Ihren eigenen Betreiber, dies zu tun erstellen. Dies ist praktisch identisch mit Tomas Beispiel, zeigt aber eine etwas andere Art und Weise zu nennen. Hier ein Beispiel:
let (~~) (x:obj) =
match x with
| :? 't as t -> t //'
| _ -> null
let o1 = "test"
let o2 = 2
let s1 = (~~o1 : string) // s1 = "test"
let s2 = (~~o2 : string) // s2 = null
Ich glaube, ich brauche ein Spiel Ausdruck für das Äquivalent in F # tun
match inputValue with | :? Type1 as type1Value -> type1Value | _ -> null
Ist das richtig?
Ja, es ist richtig. (Ihre eigene Antwort ist besser als der Rest der Antworten meiner Meinung nach.)