使用和维护IGroupedObservable

时间:2014-07-10 18:17:45

标签: c# system.reactive reactive-programming

在我的Rx代码中,我使用GroupBy创建IObservable<IGroupedObservable<T>>。从那里我希望在IGroupedObservable上执行一些转换,同时保持对组(Key)的了解。

例如,

IObservable<IGroupedObservable<T>> CreateGroup(this IObservable<T> obs)
{
    return obs.GroupBy(o => o.Something);
}

IGroupedObservable<A> Foo(this IGroupedObservable<T> obs)
{
    return obs.Select(o => new A(o));
}

IGroupedObservable<B> Bar(this IGroupedObservable<A> obs)
{
    return obs.Select(o => new B(o));
}

IObservable<IGroupedObservable<B>> stillGrouped = initialObservable.CreateGroup().Select(grouped => grouped.Foo().Bar());

当然我无法做到这一点,因为Foo中的Select()会失去IGroupedObservable-ness。

有没有人见过这个解决方案?

编辑 TLDR 我试图编写依赖于已经被分组的可观察对象的操作,并且我希望类型系统能够为我强制执行此操作。我想我可以让这些操作采用组密钥,并预先在那个密钥上执行,但那更加麻烦和慢。

1 个答案:

答案 0 :(得分:2)

嗯。

一种强力方式是复制您需要的可观察方法。像这样:

private class GroupedObservable<TKey, TElement> : IGroupedObservable<TKey, TElement>
{
    private readonly IObservable<TElement> _o;
    private readonly TKey _k;

    public TKey Key { get { return _k } }

    public GroupedObservable(TKey key, IObservable<TElement> o)
    {
        _key = key;
        _o = ;
    }

    public IDisposable Subscribe(IObserver<TElement> observer) { return _o.Subscribe(observer); }
}

public static IGroupedObservable<TKey, TResult> Select<TKey, TSource, TResult>(this IGroupedObservable<TKey, TSource> source, Func<TSource, TResult> selector)
{
    return new GroupedObservable<TKey, TResult>(source.Key, ((IObservable<TSource>)source).Select(selector));
}

随着时间的推移,你将建立一个你需要的方法库。

另一种更简单的方法是使用SelectIGroupedObservable<TKey, TElement>转换为IObservable<KeyValuePair<TKey, TElement>>

public static IObservable<KeyValuePair<TKey, TValue>> ToKV<TKey, TValue>(this IGroupedObservable<TKey, TValue> g)
{
    return g.Select(v => new KeyValuePair<TKey, TValue>(g.Key, v));
}

initialObservable.CreateGroup().Select(group => group.ToKV());