根据帖子http://cs.hubfs.net/forums/thread/3616.aspx,我需要使用如下函数将对象强制转换为接口,我已经运行了测试,这仍然是真的,错误:?>仍然没有修复.
let cast<'a> o = (box o) :?> 'a
let ci = { new Customer(18, Name = "fred") with
override x.ToString() = x.Name
interface ITalk with
member x.Talk() =
printfn "talk1111111" }
let italk = cast<ITalk> ci
if not (italk = null) then
italk.Talk()
Run Code Online (Sandbox Code Playgroud)
是否有更优雅的方式来编写上面的代码.我想创建另一个运算符来替换:?>,但是我无法获得传递的泛型类型参数,如:?>
您的cast函数的行为与C#as运算符不同 - 如果对象无法转换为指定的类型,它将抛出异常而不是返回null.因此,检查是否italk = null完成任何事情.如果你想cast在转换失败而不是抛出异常时让函数返回null,你可以像这样写:
let cast<'a when 'a : null> o =
match box o with
| :? 'a as output -> output
| _ -> null
Run Code Online (Sandbox Code Playgroud)
但是,这只适用于可空类型,它不包括结构或(默认情况下)F#类型.我可能会按原样保留您的cast功能,并tryCast使用选项.
let tryCast<'a> o =
match box o with
| :? 'a as output -> Some output
| _ -> None
Run Code Online (Sandbox Code Playgroud)
然后你可以像这样使用它:
ci |> tryCast<ITalk> |> Option.iter (fun it -> it.Talk())
Run Code Online (Sandbox Code Playgroud)
在这种情况下,Option.iter取代您的空测试.