如何检查F#对象是否实现接口

Alf*_*a07 10 f# types compilation interface typechecking

C#中的原型代码:

if(obj1 is ISomeInterface) {
   do_something
}
Run Code Online (Sandbox Code Playgroud)

F#中的代码无法编译:

match obj1 with 
| :? ISomeInterface -> do_something
| _ -> ()
Run Code Online (Sandbox Code Playgroud)

Tom*_*cek 14

要为desco和Brian的答案添加一些解释 - boxobj1值的静态类型可能不必是.NET引用类型时,需要添加.

如果obj1obj(类型别名System.Object)的类型,那么您可以使用模式匹配而不使用任何装箱,因为编译器已经知道您有一个引用类型:

let obj1 : obj = upcast (...)
match obj1 with 
| :? ISomeInterface -> (do something)
Run Code Online (Sandbox Code Playgroud)

您需要的情况box是类型obj1是泛型类型参数.在这种情况下,可以使用值类型和引用类型调用函数.添加box可确保您对引用类型执行类型测试(而不是对值类型执行,这是不可能的).


des*_*sco 13

match box obj1 with 
| :? ISomeInterface -> do_something
| _ -> ()
Run Code Online (Sandbox Code Playgroud)


ogg*_*gre 5

match box obj1 with ...完成这项工作的同时,boxF#编译器发出了一条IL指令。Box指令之所以危险,是因为在某些情况下它会变慢。

如果您知道obj1 已经是引用类型,:> obj建议使用更快的方法:

match obj1 :> obj with
    | :? ISomeInterface -> (do something)
Run Code Online (Sandbox Code Playgroud)

obj1 :> obj等效于C#(object)obj1类型的强制转换操作。此外,当在Release配置中构建项目时,F#编译器会优化过度的转换操作,因此在这种情况下,您可以获得最快的代码。