如何在 F# 中检查接口实现

How to check for an interface implementation in F#

假设我有这些类型(请原谅 C# 语法,我是 F# 的新手):

interface I { }
class A { }
class B : A, I { }

在 C# 中我可以这样做:

A a = …
bool isI = a is I;

但是,在 F# 中,有这个:

let a : A = ...

我知道 a 可能包含 B 的实例并实现 I。但是,这会导致编译错误,提示 A is not compatible with I:

let isI = a :? I

但是,这有效:

let isI = a :> obj :? I

怎么会? a :? I 既不是悲观的也不是悲观的,当然。但是它如何与 obj 一起工作?接口是否以某种方式算作对象子类?

我认为答案已在 the docs 中暗示:

Returns true if the value matches the specified type (including if it is a subtype); otherwise, returns false (type test operator).

如果您参考 7.9 动态类型测试模式 中的 the spec,它确认这是一个编译时约束:

An error occurs if type cannot be statically determined to be a subtype of the type of the pattern input

接口在层次结构中是 'higher',它是 不是 AA 的子类型。

在 mucn 中同样如此,这也不编译:

let isObj = a :? obj

首先向上转换为 obj,然后您可以检查类型是否为 I,因为这是 obj.

的子类型