繁体   English   中英

Rx:EnumerableEx.For()vs Enumerable.SelectMany()

[英]Rx: EnumerableEx.For() vs Enumerable.SelectMany()

System.Interactive.dll包含一个For()方法,具有以下实现:

IEnumerable<TResult> For<TSource, TResult>(
    IEnumerable<TSource> source,
    Func<TSource, IEnumerable<TResult>> resultSelector)
{
    return source.Select<TSource, IEnumerable<TResult>>(resultSelector).Concat<TResult>();
}

我错过了什么或者这相当于现有的Enumerable.SelectMany() ,减去this

IEnumerable<TResult> SelectMany<TSource, TResult>(
    this IEnumerable<TSource> source,
    Func<TSource, IEnumerable<TResult>> selector)

好问题。 它们产生相同的结果,但内部实现完全不同。

EnumerableEx.For将被添加到System.Interactive中以维持IObservable和IEnumerables之间的二元性。 请注意,Observable.For和Observable.SelectMany是不同的:

IObservable<TResult> For<TSource, TResult>(IEnumerable<TSource> source, Func<TSource, IObservable<TResult>> resultSelector)

对,

IObservable<TResult> SelectMany<TSource, TResult>(this IObservable<TSource> source, Func<TSource, IObservable<TResult>> selector)

因此,您希望EnumerableEx.For具有此签名,而不是它实际拥有的签名:

IEnumerable<TResult> For<TSource, TResult>(**IObservable**<TSource> source, Func<TSource, IEnumerable<TResult>> resultSelector)

但是,它显然不需要IObservable源。 也许它的意思是。 我会在Rx论坛上问你的问题,看看Rx团队是否有答案。

它们看起来像我的等效功能。 SelectMany是IEnumerable上的扩展方法,而.For在EnumerableEx上作为静态方法编写,因此它们的调用方式不同。

    foreach(var s in list.SelectMany(Filter))
    {
        // ...
    }

    foreach (var s in EnumerableEx.For(list, Filter))
    {
        // ...
    }

我确定使用每一个都有特定的原因。

我的猜测是SelectMany动态遍历所有内容,而Concat(在For中)遍历所有外部IEnumerable元素,然后开始注册并迭代它们。

换句话说,Concat使用一组固定的IEnumerable,即使它将它们作为IEnumerable接收它们。 因此,在For中,甚至在返回第一个TResult之前创建了整个IEnumerable集。 在SelectMany中,您会立即收到一个TResult。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM