C#中的原型代码:
if(obj1 is ISomeInterface) {
do_something
}
F#中的代码无法编译:
match obj1 with
| :? ISomeInterface -> do_something
| _ -> ()
答案 0 :(得分:14)
要为desco和Brian的答案添加一些解释 - 当box
值的静态类型可能不一定是.NET引用类型时,需要添加obj1
。
如果obj1
的类型是obj
(System.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 ...
我想(从我的手机打字:)