代码之家  ›  专栏  ›  技术社区  ›  dahlbyk

rx:EnumerableEx.for()与Enumerable.Selectmany()。

  •  7
  • dahlbyk  · 技术社区  · 14 年前

    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)
    
    3 回复  |  直到 13 年前
        1
  •  1
  •   Richard Anthony Hein    14 年前

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

    EnumerableEx.for将被添加到System.Interactive中,以保持iobservable和ienumerable之间的对偶性。注意observable.for和observable.selectmany是不同的:

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

    VS,

    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)
    

    但是,它显然不需要一个不可观测的源。也许是故意的。我会在RX论坛上问你问题,看看RX团队是否有答案。

        2
  •  0
  •   Ray Henry    14 年前

    它们对我来说就像是等价的功能。SelectMany是IEnumerable上的扩展方法。for在EnumerableEx上作为静态方法写入,因此它们的调用方式不同。

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

    我相信使用每一个都有具体的原因。

        3
  •  0
  •   akarnokd    13 年前

    我的猜测是selectmany动态遍历所有内容,而concat(in for) 遍历它的所有外部IEnumerable元素,然后开始使用它们进行注册和迭代。

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