当类型参数是协变的时候,与C#相比,F#是否处理不同的继承?

时间:2014-10-27 22:14:52

标签: f# c#-to-f#

在使用C#here中的等效代码时,我使用以下代码向我发送了一些新内容。编译器给出了多个错误,基本上告诉source.Publish()中创建的IConnectableObservableIObservable不匹配,即使它是从它派生的(根据链接的MSDN文章)。

在这种情况下,F#中有关于继承的C#有什么不同,或者有人可以提供有关正在发生的事情的指针吗?我刚刚做了一个我看不到的拼写错误?关于协方差的标题是什么,这只是一个疯狂的猜测,因为我至少暂时没有想法。所以,写一些地方可能会帮助我和其他人......

许多错误消息的一个示例:

  

方法“创建”没有重载匹配。可用的重载如下所示(或在错误列表窗口中)。

     

方法'Switch'没有重载匹配。可用的重载如下所示(或在错误列表窗口中)。

     

错误可能的重载:'(扩展名)IObservable.Switch<'TSource>():   的IObservable< 'TSource>'。类型约束不匹配。类型       的IObservable< IConnectableObservable<'B个;>与类型不兼容       的IObservable<&的IObservable LT;'一>>类型'IObservable<'a>'与“IConnectableObservable<'b>'。

类型不匹配
open System.Reactive.Concurrency
open System.Reactive.Disposables
open System.Reactive.Subjects
open System.Reactive.Linq


type Observable with
    static member inline Suspendable(source: IObservable<_>, suspend: IObservable<bool>, isSuspendedInitially: bool): IObservable<_> =
        Observable.Create<_>(fun observer ->
            let shared = source.Publish()
            let pausable =
                suspend.StartWith(isSuspendedInitially)
                    .TakeUntil(shared.LastOrDefaultAsync())
                    .DistinctUntilChanged()
                    .Select(fun p -> if p then shared else Observable.Empty<_>())
                    .Switch()
            new CompositeDisposable(pausable.Subscribe(observer), shared.Connect()))

相应的C#代码

public static class RxExtensions
{
    public static IObservable<T> Suspendable<T>(this IObservable<T> stream, IObservable<bool> suspend, bool isSuspendedInitially)
    {            
        return Observable.Create<T>(o =>
        {
            var shared = stream.Publish();
            var pausable = suspend
                .StartWith(isSuspendedInitially)
                .TakeUntil(shared.LastOrDefaultAsync())
                .DistinctUntilChanged()
                .Select(p => p ? shared : Observable.Empty<T>())
                .Switch();
            return new CompositeDisposable(pausable.Subscribe(o), shared.Connect());                
        });
    }
}

1 个答案:

答案 0 :(得分:2)

这有点棘手,但您需要添加两个向上转换:sharedIObservable<_>,并将lambda函数的结果添加到IDisposable。这些将隐含在C#中,但需要在F#中显式:

type Observable with
    static member inline Suspendable (source: IObservable<_>, 
                                      suspend: IObservable<bool>, 
                                      isSuspendedInitially: bool): IObservable<'a> =
        Observable.Create<_>(fun observer ->
            let shared = source.Publish()
            let pausable = 
                suspend.StartWith(isSuspendedInitially)
                    .TakeUntil(shared.LastOrDefaultAsync())
                    .DistinctUntilChanged()
                    .Select(fun p -> if p then shared :> IObservable<_> 
                                          else Observable.Empty<_>())
                    .Switch()
            new CompositeDisposable(pausable.Subscribe(observer), 
                                    shared.Connect()) :> IDisposable)