4

我有以下使用反应式扩展的代码片段:

    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
    )

这行得通。但是,如果我将向上转换为 IDisposable,则代码将无法编译,并引用模棱两可的重载。然而 CompositeDisposable 是一个 IDisposable。为什么类型推理引擎无法解决这个问题?请注意,我几乎一直在 C# 中使用此模式,从 Observable.Create 返回 CompositeDisposable,而无需向上转换。

4

1 回答 1

8

正如@kvb 所说,函数不支持变化,因此接口和子类需要向上转换。

这是一个演示子类行为的小示例:

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

否则,你必须按照你的例子描述的那样做一个小小的向上转换。

于 2012-12-21T07:23:46.073 回答