Domanda

In C # che posso fare:

var castValue = inputValue as Type1

In F #, posso fare:

let staticValue = inputValue :> Type1
let dynamicValue = inputValue :?> Type1

Ma nessuno dei due è l'equivalente del C # 's as parola chiave.

Credo che ho bisogno di fare un'espressione partita per l'equivalente in F #

match inputValue with
| :? Type1 as type1Value -> type1Value
| _ -> null

È corretto?

È stato utile?

Soluzione

Per quanto ne so, F # non ha alcun built-in operatore equivalente a C # as quindi è necessario scrivere qualche espressione più complicato. In alternativa al codice utilizzando match, si potrebbe anche usare if, perché il :? operatore può essere utilizzato allo stesso modo come is in C #:

let res = if (inputValue :? Type1) then inputValue :?> Type1 else null

È possibile, naturalmente, scrivere una funzione per incapsulare questo comportamento (scrivendo una semplice funzione generica che prende un Object e l'inserisce al parametro di tipo generico specificato):

let castAs<'T when 'T : null> (o:obj) = 
  match o with
  | :? 'T as res -> res
  | _ -> null

Questo restituisce implementazione null, quindi è necessario che il parametro di tipo ha null come un valore adeguato (in alternativa, è possibile utilizzare Unchecked.defaultof<'T>, che equivale a default(T) in C #). Ora è possibile scrivere semplicemente:

let res = castAs<Type1>(inputValue)

Altri suggerimenti

I userebbe un modello attivo. Qui è l'uso che ho:

let (|As|_|) (p:'T) : 'U option =
    let p = p :> obj
    if p :? 'U then Some (p :?> 'U) else None

Ecco un esempio dell'uso di 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

È possibile creare il proprio operatore per fare questo. Questo è praticamente identico all'esempio di Tomas, ma mostra un modo leggermente diverso per chiamare. Ecco un esempio:

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
  

Credo che ho bisogno di fare un'espressione partita per l'equivalente in F #

     

match inputValue with | :? Type1 as type1Value -> type1Value | _ -> null

     

È corretto?

Sì, è corretto. (La tua risposta è migliore rispetto al resto delle risposte a mio parere).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top