Q:

C# reactive extension - Join() overloads

Reactive Extensions has the extension method:
Join(this IObservable<TLeft> left, IObservable<TRight> right, 
    Func<TLeft, IObservable<TLeftDuration>> leftDurationSelector, 
    Func<TRight, IObservable<TRightDuration>> rightDurationSelector, 
    Func<TLeft, TRight, TResult> resultSelector)

However, there is no overload that also takes a Func<TLeft, TRight, bool> as a join condition. As a result this method returns a full Cartesian product of the left and right. 
I have implemented this as 
    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);
    }

As I am using this more I am wondering if I might require more similar methods (perhaps outer joins - whatever that means for Observables). Rather than trying to implement them all (and bring in the potential for bugs and sub-optimal code) I was wondering if someone else has had the same problem and if there are libraries that have already been written. 
Any ideas?

A:

I think you have misunderstood how reactive joins work. The join condition is event coincidence, not a binary operation you supply. Basically each event gets a duration attached to it, and events from left and right sources that exist at the same time are joined. Have a look at this video for more explanation.
The result of a reactive join is the Cartesian product if the durations are non-terminating - as you have made them in your sample. What you are doing is going to give some very poor performance characteristics.
Can you provide marble diagrams, unit tests and/or example scenarios of what you are trying to achieve?
I suspect there will be a better way without using a Join.

