C#我可以这样做:

var castValue = inputValue as Type1

在F#我可以这样做:

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

但他们都不是同等的C#'s的关键字 as.

我猜我需要一个匹配的表达的同等F#

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

这是正确的?

有帮助吗?

解决方案

据我所知,F#没有任何内置的操作等同于C#as所以你需要写一些更复杂的表达式。或者你的代码中使用match,你也可以使用if,因为运营商:?可以在C#中以同样的方式作为is

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

可以当然写一个函数来封装这种行为(通过编写一个简单的通用函数,它接受一个Object和铸件到指定的一般类型参数):

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

此实现返回null,所以它要求的类型参数具有null作为一个适当的值(或者,可以使用Unchecked.defaultof<'T>,这相当于在default(T) C#)。现在你可以这样写:

let res = castAs<Type1>(inputValue)

其他提示

我会用一个有源图案。这里是一个我使用:

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

下面是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

您可以创建自己的运营商做到这一点。这实际上与托马斯的例子,但显示了稍微不同的方式来调用它。下面是一个例子:

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
  

我想我需要为F#等效

做一个匹配表达式      

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

     

这是正确的吗?

是的,这是正确的。 (你自己的答案比在我看来,答案都强。)

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top