C# and F# casting - specifically the 'as' keyword
In C# I can do:
var castValue = inputValue as Type1
In F#, I can do:
let staticValue = inputValue :> Type1
let dynamicValue = inputValue :?> Type1
But neither of them is the equivalent of the C#'s keyword as开发者_如何学运维
.
I guess I need to do a match expression for the equivalent in F#
match inputValue with
| :? Type1 as type1Value -> type1Value
| _ -> null
Is this correct?
As far as I know, F# doesn't have any built-in operator equivalent to C# as
so you need to write some more complicated expression. Alternatively to your code using match
, you could also use if
, because the operator :?
can be use in the same way as is
in C#:
let res = if (inputValue :? Type1) then inputValue :?> Type1 else null
You can of course write a function to encapsulate this behavior (by writing a simple generic function that takes an Object
and casts it to the specified generic type parameter):
let castAs<'T when 'T : null> (o:obj) =
match o with
| :? 'T as res -> res
| _ -> null
This implementation returns null
, so it requires that the type parameter has null
as a proper value (alternatively, you could use Unchecked.defaultof<'T>
, which is equivalent to default(T)
in C#). Now you can write just:
let res = castAs<Type1>(inputValue)
I would use an active pattern. Here is the one I use:
let (|As|_|) (p:'T) : 'U option =
let p = p :> obj
if p :? 'U then Some (p :?> 'U) else None
Here is a sample usage of 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
You can create your own operator to do this. This is virtually identical to Tomas's example, but shows a slightly different way to call it. Here's an example:
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
Yes; see, except below from: What does this C# code look like in F#? (part one: expressions and statements)
C# has "is" and "as" operators for type tests. F# uses a particular pattern in a match for this. So this C# code:
if (animal is Dog)
{
Dog dog = animal as Dog;
// …
}
else if (animal is Cat)
{
Cat cat = animal as Cat;
// …
}
becomes this F# code:
match animal with
| :? Dog as dog -> // …
| :? Cat as cat -> // …
where ":? type" is a type test, and "as ident" names the resulting value of that type if the type test succeeds.
I guess I need to do a match expression for the equivalent in F#
match inputValue with | :? Type1 as type1Value -> type1Value | _ -> null
Is this correct?
Yes, it's correct. (Your own answer is better than the rest of the answers in my opinion.)
精彩评论