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

时间:2011-03-20 13:05:43

标签: interface f# types compilation typechecking

C#中的原型代码:

if(obj1 is ISomeInterface) {
   do_something
}

F#中的代码无法编译:

match obj1 with 
| :? ISomeInterface -> do_something
| _ -> ()

4 个答案:

答案 0 :(得分:14)

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

如果obj1的类型是objSystem.Object的类型别名),那么你可以使用模式匹配而不需要任何装箱,因为编译器已经知道你有一个引用类型:< / p>

let obj1 : obj = upcast (...)
match obj1 with 
| :? ISomeInterface -> (do something)

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

答案 1 :(得分:13)

match box obj1 with 
| :? ISomeInterface -> do_something
| _ -> ()

答案 2 :(得分:4)

match box obj1 with ...完成工作时,F#编译器会发出box IL指令。 Box指令很危险,因为在某些情况下它往往很慢。

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

match obj1 :> obj with
    | :? ISomeInterface -> (do something)

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

答案 3 :(得分:3)

match box obj1 with ...

我想(从我的手机打字:)