C# and F# casting - specifically the 'as' keyword

走远了吗. 提交于 2019-11-27 17:12:12

问题


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?


回答1:


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)



回答2:


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



回答3:


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



回答4:


Yes; see also

What does this C# code look like in F#? (part one: expressions and statements)




回答5:


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



来源:https://stackoverflow.com/questions/2361851/c-sharp-and-f-casting-specifically-the-as-keyword

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!