我有以下使用反应式扩展程序的代码段:
let value : 't = ...
Observable.Create<'t>(fun observer ->
let subject = new BehaviorSubject<'t>(value)
let d0 = subject.Subscribe(observer)
let d1 = observable.Subscribe(subject)
new CompositeDisposable(d0, d1) :> IDisposable
)
这很有效。但是,如果我将upcast丢弃到IDisposable,则代码将失败 编译,引用模糊的重载。但是CompositeDisposable是一个 IDisposable接口。为什么类型推理引擎无法解决此问题?注意我几乎一直在C#中从Observable.Create返回CompositeDisposable,而不必进行upcast。
答案 0 :(得分:8)
正如@kvb所说,函数不支持方差,因此接口和子类需要upcast。
这是一个展示子类行为的小例子:
type A() =
member x.A = "A"
type B() =
inherit A()
member x.B = "B"
let f (g: _ -> A) = g()
let a = f (fun () -> A()) // works
let b = f (fun () -> B()) // fails
如果您编写函数f
,则添加类型约束可能会有所帮助:
// This works for interface as well
let f (g: _ -> #A) = g()
let a = f (fun () -> A()) // works
let b = f (fun () -> B()) // works
否则,你必须按照你所描述的例子做一个litle upcast。