Có 4 chữ ký quá tải cho Enumerable.SelectMany. Để đơn giản, chúng tôi bỏ qua hai chữ ký với đối số int. Vì vậy, chúng tôi có 2 chữ ký cho SelectMany:Trình biên dịch C# chọn SelectMany như thế nào khi dịch biểu thức 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
)
Câu hỏi của tôi là: cách trình biên dịch C# chọn SelectMany khi dịch biểu thức LINQ sang lời gọi phương thức mở rộng?
Về cơ bản, nếu có nhiều từ trong biểu thức LINQ, sẽ có SelectMany. Nhưng, có vẻ như trình biên dịch C# chỉ chọn chữ ký thứ hai. Chữ ký đầu tiên không bao giờ được sử dụng.
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);
}
Với sự giúp đỡ của Reflector, tôi có thể thấy rằng trên biểu thức LINQ được dịch sang
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();
})
Ví dụ ở trên bao gồm 3 loại. Vì vậy, nó là hợp lý để chọn chữ ký SelectMany thứ hai. Tuy nhiên, đối với ví dụ dưới đây, chỉ có một loại có liên quan, nó vẫn chọn chữ ký thứ hai.
IEnumerable<int> en4 =
from i1 in en1
from i2 in Enumerable.Range(0, i1)
select i2;
Nó được dịch thành:
en1.SelectMany<int, int, int>(delegate (int i1) {
return Enumerable.Range(0, i1);
}, delegate (int i1, int i2) {
return i2;
})
Vì vậy, tôi không thể tìm thấy một trường hợp đó biểu thức LINQ được dịch sang chữ ký SelectMany đầu tiên. Có trường hợp như vậy không?
Nếu chữ ký SelectMany đầu tiên không được sử dụng, thì nó tồn tại chỉ vì nó là BIND của đơn nguyên trong lập trình hàm?
Có lẽ câu hỏi có thể là: tại sao chúng ta có 2 chữ ký của SelectMany?
Cảm ơn.
Thực sự ... hàm void trả về nội dung nào đó và không ai nhận xét về nó? –