Hay 4 firmas sobrecargadas para Enumerable.SelectMany. Para hacerlo simple, no hacemos caso de las dos firmas con int argumento. Así que tenemos 2 firmas para SelectMany:¿Cómo C# compilador elige SelectMany cuando traduce la expresión LINQ?
public static IEnumerable<TResult> SelectMany<TSource, TResult>(
this IEnumerable<TSource> source,
Func<TSource, IEnumerable<TResult>> selector
)
public static IEnumerable<TResult> SelectMany<TSource, TCollection, TResult>(
this IEnumerable<TSource> source,
Func<TSource, IEnumerable<TCollection>> collectionSelector,
Func<TSource, TCollection, TResult> resultSelector
)
Mi pregunta es: ¿Cómo elegir compilador de C# SelectMany al traducir la expresión LINQ a la invocación de métodos de extensión?
Básicamente, si hay múltiples de en expresión LINQ, habrá SelectMany. Pero, parece que el compilador de C# solo elige la segunda firma. La primera firma nunca se usa.
IEnumerable<int> en1 = Enumerable.Range(1, 3);
IEnumerable<double> en2 = new double[] { 1.0, 3.14 };
IEnumerable<string> en3 =
from i1 in en1
from i2 in en2
select (i1 * i2).ToString();
foreach (var i in en3)
{
Console.WriteLine(i);
}
Con la ayuda del reflector, puedo ver que por encima de la expresión LINQ se traduce en
en1.SelectMany<int, double, string>(delegate (int i1) {
return en2;
}, delegate (int i1, double i2) {
double CS$0$0000 = i1 * i2return CS$0$0000.ToString();
})
El ejemplo de arriba implica 3 tipos. Entonces, es razonable seleccionar la segunda firma de SelectMany. Sin embargo, para el ejemplo siguiente, solo está involucrado un tipo, aún selecciona la segunda firma.
IEnumerable<int> en4 =
from i1 in en1
from i2 in Enumerable.Range(0, i1)
select i2;
se traduce en:
en1.SelectMany<int, int, int>(delegate (int i1) {
return Enumerable.Range(0, i1);
}, delegate (int i1, int i2) {
return i2;
})
Por lo tanto, no puedo encontrar un caso que la expresión LINQ se traduce en la primera firma SelectMany. ¿Hay tal caso?
Si no se utiliza la primera firma SelectMany, entonces existe sólo porque se trata de BIND mónada en la programación funcional?
Tal vez la pregunta puede ser: ¿por qué tenemos 2 firmas de SelectMany?
Gracias.
Realmente ... ¿una función nula que devuelve algo y nadie lo comenta? –