2012-02-02 27 views
14

thể trùng lặp:
Nested “from” LINQ query expressed with extension methodsNice, chéo sạch tham gia trong LINQ chỉ sử dụng phương pháp khuyến nông

Tôi chắc chắn điều này đã được yêu cầu trước đây, nhưng tôi thành thật không thể tìm thấy bất cứ điều gì .

tôi tò mò những gì các cú pháp tương đương sẽ là sau chỉ sử dụng được xây dựng trong phương pháp khuyến nông LINQ:

var z1 = 
    from x in xs 
    from y in ys 
    select new { x, y }; 

tôi có thể nhận được kết quả tương tự với điều này:

var z2 = xs.SelectMany(x => ys.Select(y => new { x, y })); 

Nhưng nó tạo ra mã IL khác nhau, và mã có một chút phức tạp và khó hiểu. Có cách nào sạch hơn để làm điều này với các phương pháp mở rộng?


Dưới đây là toàn bộ phương pháp thử nghiệm của tôi như được viết:

private void Test() 
{ 
    var xs = new[] { 1D, 2D, 3D }; 
    var ys = new[] { 4D, 5D, 6D }; 

    var z1 = 
     from x in xs 
     from y in ys 
     select new { x, y }; 

    var z2 = xs.SelectMany(x => ys.Select(y => new { x, y })); 
} 

Đây là [Edit: C# interp của] IL mã (sử dụng ILSpy):

private void Test() 
{ 
    double[] xs = new double[] 
    { 
     1.0, 
     2.0, 
     3.0 
    }; 
    double[] ys = new double[] 
    { 
     4.0, 
     5.0, 
     6.0 
    }; 
    var z = 
     from x in xs 
     from y in ys 
     select new 
     { 
      x = x, 
      y = y 
     }; 
    var z2 = xs.SelectMany((double x) => 
     from y in ys 
     select new 
     { 
      x = x, 
      y = y 
     }); 
} 
+7

eh, đó không phải là mã il? –

+1

Điều đó giống như một giải thích C# từ việc tháo gỡ thay vì IL. –

+4

Eric Lippert trả lời khá nhiều câu hỏi tương tự hôm nay ở đây: http://stackoverflow.com/questions/9115675/nested-from-linq-query-expressed-with-extension-methods/9117009#9117009 – hvd

Trả lời

33

Một cách sẽ được :

var z2 = xs.SelectMany(x => ys, (x, y) => new {x, y}); 
+0

+1: Đây có lẽ là giải pháp tốt nhất. – Douglas

+1

@Magnus, đây là nó, +1 và cảm ơn. Tôi đã không nhận ra có một sự quá tải của 'SelectMany' cho phép bạn làm điều đó. Tôi cũng đã học được, nhờ nhận xét của @ Daniel ở trên, rằng tôi có thể xem phiên bản phương thức mở rộng hơn là cú pháp truy vấn trong ILSpy, và nó đã đưa ra câu trả lời cơ bản của bạn. – devuxer

6

Nếu bạn thực sự muốn sử dụng một phương pháp mở rộng LINQ duy nhất, khi đó một ứng cử viên khác sẽ là Join, với các hàm outerKeySelectorinnerKeySelector được xác định sao cho chúng sẽ luôn tạo ra các giá trị bằng nhau.

var z3 = xs.Join(ys, x => true, y => true, (x, y) => new { x, y }); 

Điều này, tuy nhiên, có thể cung cấp mã IL phức tạp hơn giải pháp lồng nhau from. Ngẫu nhiên, MSDN sử dụng lồng nhau from trong ví dụ của nó cho một tham gia chéo; xem đoạn mã đầu tiên trong How to: Perform Custom Join Operations (C# Programming Guide).

Các vấn đề liên quan