C#被动扩展 - Join()重载

时间:2013-12-05 14:22:53

标签: c# system.reactive

Reactive Extensions有扩展方法:

Join(this IObservable<TLeft> left, IObservable<TRight> right, 
    Func<TLeft, IObservable<TLeftDuration>> leftDurationSelector, 
    Func<TRight, IObservable<TRightDuration>> rightDurationSelector, 
    Func<TLeft, TRight, TResult> resultSelector)

但是,没有重载也需要Func<TLeft, TRight, bool>作为连接条件。结果,此方法返回左右的完整笛卡尔积。

我已将其实现为

    public static IObservable<TResult> Join<TLeft, TRight, TResult>(
        this IObservable<TLeft> left, IObservable<TRight> right, Func<TLeft, TRight, bool> joinCondition,
        Func<TLeft, TRight, TResult> resultSelector)
    {
        return left.Join(right, l => Observable.Never<TLeft>(), r => Observable.Never<TRight>(),
            (l, r) => new Tuple<TLeft, TRight>(l, r))
            .Where(CurryTuple(joinCondition))
            .Select(CurryTuple(resultSelector));
    } 

    private static Func<Tuple<TLeft, TRight>, TResult> CurryTuple<TLeft, TRight, TResult>(Func<TLeft, TRight, TResult> func)
    {
        return tuple => func(tuple.Item1, tuple.Item2);
    }

当我更多地使用它时,我想知道我是否可能需要更多类似的方法(可能是外连接 - 无论对于Observables意味着什么)。而不是试图实现它们(并带来潜在的错误和次优代码),我想知道是否有其他人遇到了同样的问题,是否有已经编写过的库。

有什么想法吗?

1 个答案:

答案 0 :(得分:0)

我认为你误解了反应联合的运作方式。连接条件是事件重合,而不是您提供的二进制操作。基本上每个事件都会附加一个持续时间,同时存在来自同时存在的左右源的事件。 Have a look at this video了解更多信息。

如果持续时间不是终止的,则反应性连接的结果是笛卡尔积 - 正如您在样本中制作的那样。你正在做的是会给出一些非常差的性能特征。

您能提供大理石图表,单元测试和/或您想要实现的示例场景吗?

我怀疑没有使用Join会有更好的方法。