C# e F# fundindo - especificamente a palavra -chave 'como'
Pergunta
Em C# eu posso fazer:
var castValue = inputValue as Type1
Em F#, posso fazer:
let staticValue = inputValue :> Type1
let dynamicValue = inputValue :?> Type1
Mas nenhum deles é o equivalente à palavra -chave C# as
.
Acho que preciso fazer uma expressão de partida para o equivalente em f#
match inputValue with
| :? Type1 as type1Value -> type1Value
| _ -> null
Isso está correto?
Solução
Até onde eu sei, F# não tem nenhum operador interno equivalente a C# as
Então você precisa escrever uma expressão mais complicada. Alternativamente ao seu código usando match
, você também pode usar if
, porque o operador :?
pode ser usado da mesma maneira que is
Em C#:
let res = if (inputValue :? Type1) then inputValue :?> Type1 else null
É claro que você pode escrever uma função para encapsular esse comportamento (escrevendo uma função genérica simples que leva um Object
e o lança para o parâmetro de tipo genérico especificado):
let castAs<'T when 'T : null> (o:obj) =
match o with
| :? 'T as res -> res
| _ -> null
Esta implementação retorna null
, então exige que o parâmetro do tipo tenha null
Como um valor adequado (alternativamente, você pode usar Unchecked.defaultof<'T>
, que é equivalente a default(T)
em C#). Agora você pode escrever apenas:
let res = castAs<Type1>(inputValue)
Outras dicas
Eu usaria um padrão ativo. Aqui está o que eu uso:
let (|As|_|) (p:'T) : 'U option =
let p = p :> obj
if p :? 'U then Some (p :?> 'U) else None
Aqui está um uso de amostra de 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
Você pode criar seu próprio operador para fazer isso. Isso é praticamente idêntico ao exemplo de Tomas, mas mostra uma maneira um pouco diferente de chamá -lo. Aqui está um exemplo:
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
Sim; Veja também
Como é esse código C# em f#? (Parte um: Expressões e declarações)
Acho que preciso fazer uma expressão de partida para o equivalente em f#
match inputValue with | :? Type1 as type1Value -> type1Value | _ -> null
Isso está correto?
Sim está correto. (Sua própria resposta é melhor do que o resto das respostas na minha opinião.)