C # et F # coulée - en particulier le « comme » mot-clé
Question
En C # je peux faire:
var castValue = inputValue as Type1
En F #, je peux faire:
let staticValue = inputValue :> Type1
let dynamicValue = inputValue :?> Type1
Mais aucun d'entre eux est l'équivalent de as
mot-clé du C #.
Je suppose que je dois faire une expression de correspondance pour l'équivalent en F #
match inputValue with
| :? Type1 as type1Value -> type1Value
| _ -> null
Est-ce correct?
La solution
Pour autant que je sache, F # n'a pas de intégré dans l'opérateur équivalent à C # as
de sorte que vous devez écrire une expression plus compliquée. Vous pouvez également à votre code à l'aide match
, vous pouvez également utiliser if
, parce que le :?
opérateur peut être utilisé de la même manière que is
en C #:
let res = if (inputValue :? Type1) then inputValue :?> Type1 else null
Vous pouvez bien sûr écrire une fonction pour résumer ce comportement (en écrivant une fonction générique simple qui prend un Object
et il jette au paramètre de type générique spécifié):
let castAs<'T when 'T : null> (o:obj) =
match o with
| :? 'T as res -> res
| _ -> null
Cette implémentation retourne null
, donc il faut que le paramètre de type a null
comme une valeur appropriée (alternativement, vous pouvez utiliser Unchecked.defaultof<'T>
, ce qui équivaut à default(T)
en C #). Maintenant, vous pouvez simplement écrire:
let res = castAs<Type1>(inputValue)
Autres conseils
J'utiliser un modèle actif. Voici celui que j'utilise:
let (|As|_|) (p:'T) : 'U option =
let p = p :> obj
if p :? 'U then Some (p :?> 'U) else None
Voici un exemple de l'utilisation 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
Vous pouvez créer votre propre opérateur de le faire. Ceci est pratiquement identique à l'exemple de Tomas, mais montre une manière légèrement différente de l'appeler. Voici un exemple:
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
Je suppose que je dois faire une expression de correspondance pour l'équivalent en F #
match inputValue with | :? Type1 as type1Value -> type1Value | _ -> null
Est-ce correct?
Oui, il est exact. (Votre propre réponse est mieux que le reste des réponses à mon avis.)