2010-10-06 7 views
7

System.Interactive.dll incluye un método For() con la siguiente implementación:Rx: EnumerableEx.For() vs Enumerable.SelectMany()

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

Me estoy perdiendo algo o esto es equivalente a la Enumerable.SelectMany() existente, menos this?

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

Respuesta

1

Buena pregunta. Producen los mismos resultados, pero las implementaciones internas son bastante diferentes.

EnumerableEx.For se habría agregado a System.Interactive para mantener la dualidad entre IObservable e IEnumerables. Tenga en cuenta que Observable.For y Observable.SelectMany son diferentes:

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) 

Por lo tanto lo que espera que EnumerableEx.For tendría esta firma, en lugar de la que en realidad tiene :

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

Sin embargo, obviamente no toma una fuente IObservable. Quizás fue destinado a. Haría su pregunta en los foros de Rx, para ver si el equipo de Rx tiene una respuesta.

+0

Preguntado en los foros de Rx: http://social.msdn.microsoft.com/Forums/en-US/rx/thread/48992ccb-d2dc-4de4-8525-d88ce8622554 – dahlbyk

+0

Confirmado por Bart De Smet en el foro de Rx . – dahlbyk

0

Me parecen una funcionalidad equivalente. SelectMany es un método de extensión en un IEnumerable y .For está escrito como un método estático en EnumerableEx, por lo que se llaman de manera diferente.

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

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

Estoy seguro de que hay razones específicas para usar cada una.

0

Supongo que SelectMany atraviesa todo dinámicamente, mientras que Concat (en For) atraviesa todos sus elementos externos de IEnumerable antes de comenzar a registrarse e iterar sobre ellos.

En otras palabras, Concat funciona con un conjunto fijo de IEnumerable incluso si los recibe como IEnumerable. Por lo tanto, en For, se crea todo el conjunto de IEnumerable incluso antes de devolver el primer TResult. En SelectMany, recibe un TResult al instante.

+0

Dado que todos los operadores involucrados (SelectMany, Select y Concat) son diferidos, no estoy seguro de que cualquier diferencia en la implementación se traduzca en un comportamiento final diferente. Algunas pruebas con efectos secundarios en varios puntos en el selector de cada operador parecen dar siempre el mismo resultado diferido. – dahlbyk

+0

En concat, ya sabes con cuántos IEnumerables necesitas trabajar, mientras que en SelectMany, su cantidad depende de cuántos elementos lleguen de la fuente. Para fuentes de entrada de tamaño constante, ambos deberían producir el mismo – akarnokd

Cuestiones relacionadas