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?

Était-ce utile?

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.)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top