Es gibt 4 überladene Signaturen für Enumerable.SelectMany. Um es einfach zu machen, ignorieren wir die beiden Signaturen mit int Argument. So haben wir zwei Unterschriften für Select:Wie C# -Compiler wählen Sie SelectMany beim Übersetzen von LINQ-Ausdruck?
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
)
Meine Frage ist: wie C# -Compiler Select wählen, wenn LINQ Ausdruck Erweiterung Methodenaufruf zu übersetzen?
Grundsätzlich, wenn es mehrere von in LINQ Ausdruck gibt, wird SelectMany sein. Aber es scheint, dass der C# -Compiler nur die zweite Signatur auswählt. Die erste Signatur wird niemals verwendet.
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);
}
Mit Hilfe von Reflektor, kann ich über LINQ Ausdruck, dass in
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();
})
übersetzt Obiges Beispiel 3 Arten umfasst. Daher ist es sinnvoll, die zweite SelectMany-Signatur auszuwählen. Für das folgende Beispiel ist jedoch nur ein Typ beteiligt, es wählt immer noch die zweite Signatur aus.
IEnumerable<int> en4 =
from i1 in en1
from i2 in Enumerable.Range(0, i1)
select i2;
Es in übersetzt:
en1.SelectMany<int, int, int>(delegate (int i1) {
return Enumerable.Range(0, i1);
}, delegate (int i1, int i2) {
return i2;
})
Also, ich kann nicht einen Fall feststellen, dass LINQ-Ausdruck in die erste Select Signatur übersetzt. Gibt es einen solchen Fall?
Wenn die erste SelectMany-Signatur nicht verwendet wird, dann existiert sie nur, weil sie in der funktionalen Programmierung BIND von monad ist?
Vielleicht kann die Frage sein: Warum haben wir 2 Signaturen von SelectMany?
Danke.
Wirklich ... eine Leerfunktion, die etwas zurückgibt, und niemand kommentiert? –