C#和F#强制转换 – 特别是’as’关键字

在C#我可以这样做:

var castValue = inputValue as Type1 

在F#中,我可以这样做:

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

但它们都不等同于C#的关键字。

我想我需要为F#中的等价物做一个匹配表达式

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

它是否正确?

据我所知,F#没有任何与C#等效的内置运算符as所以你需要编写一些更复杂的表达式。 或者使用match代码,你也可以使用if ,因为运算符:? 可以像在C#中一样使用:

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

您当然可以编写一个函数来封装此行为(通过编写一个简单的generics函数,它接受一个Object并将其强制转换为指定的generics类型参数):

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

此实现返回null ,因此它要求type参数将null作为适当的值(或者,您可以使用Unchecked.defaultof<'T> ,这相当于C#中的default(T) )。 现在你可以写:

 let res = castAs(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 

您可以创建自己的运算符来执行此操作。 这实际上与Tomas的例子相同,但显示了一种稍微不同的方式来调用它。 这是一个例子:

 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 

是; 也可以看看

这个C#代码在F#中是什么样的? (第一部分:表达和陈述)

我想我需要为F#中的等价物做一个匹配表达式

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

它是否正确?

是的,这是对的。 (在我看来,你自己的答案比其他答案要好。)