2010-03-12 64 views
9

Tôi có một phương thức với bộ sưu tập foreach lồng nhau (lặp một tập hợp các đối tượng và sau đó nhìn vào bên trong từng đối tượng). Tôi thấy trong một cuốn sách là một mô hình tốt để làm cho điều này thanh lịch hơn nhiều nhưng không thể nhớ/tìm thấy ví dụ mã. Làm thế nào khác tôi có thể làm cho điều này gọn gàng hơn?Tái cấu trúc câu lệnh forested lồng nhau

Mã chỉ là một tuyên bố lồng nhau điển hình foreach vì vậy tôi chưa cung cấp mẫu mã.

+8

Nhận xét này chỉ là một nhận xét điển hình, vì vậy tôi chưa cung cấp nhận xét! ;-) –

+2

Tôi được nhắc về cuộc thảo luận của Eric Lippert về việc tiếp tục với vòng lặp bên ngoài: http://blogs.msdn.com/ericlippert/archive/2010/01/11/continuing-to-an-outer-loop.aspx – Brian

Trả lời

5

Các giải pháp rõ ràng là để san bằng vào phương pháp.

Cũ:

void SubmitOrders() 
{ 
    var orders = GetOrders(); 
    foreach (Order o in orders) 
    { 
     foreach (OrderDetail d in o.Details) 
     { 
      // Blah... 
     } 
    } 
} 

mới:

câu trả lời
void SubmitOrders() 
{ 
    var orders = GetOrders() 
    foreach (Order o in orders) 
    { 
     SubmitOrder(o); 
    } 
} 

void SubmitOrder(Order order) 
{ 
    foreach (OrderDetail d in order.Details) 
    { 
     // Blah... 
    } 
} 

khác ở đây dường như được tập trung vào LINQ, và tôi sẽ đồng ý rằng nếu vòng của bạn không có tác dụng phụ (tức là bạn chỉ cố gắng trích xuất một số thông tin từ vòng lặp trong cùng), sau đó bạn có thể viết lại toàn bộ điều bằng cách sử dụng một hoặc hai câu lệnh LINQ đơn giản. Nếu tác dụng phụ có liên quan, sau đó chỉ cần làm theo các thực hành được kiểm tra theo thời gian của các chương trình con.

+0

Nó tương tự như thế này (trả về IEnumerable). Cảm ơn. – dotnetdev

11

Bạn sẽ phải cụ thể hơn về ý nghĩa của mình về "thanh lịch hơn", vì IMO không có gì đặc biệt là không phù hợp về lồng nhau foreach.

Điều đó đang được nói, các phương pháp mở rộng LINQ trong .NET 3.5 trở lên có thể trợ giúp (cụ thể là SelectMany).

public class Foo 
{ 
    public List<string> Strings { get; set; } 
} 

... 

List<Foo> foos = new List<Foo>(); 

foreach(string str in foos.SelectMany(f => f.Strings)) 
{ 
    ... 
} 
0

Bạn đang nghĩ đến việc gì đó như thế này?

public class YourObject{ 
    public List<OtherObject> Others { get; set; } 
} 

public class OtherObject{ 
    public void DoIt(){} 
} 

var theList = new List<YourObject>(); 

theList.ForEach(yo => yo.Others.ForEach(oo => oo.DoIt())); 
+0

'ForEach' là một phương thức trên' Danh sách ', ** không ** LINQ. –

+0

@Adam Robinson, bạn nói đúng ... –

+0

@Adam Robinson: Mặc dù người ta có thể (rất) dễ dàng viết một phương thức mở rộng 'ForEach' trên 'IEnumerable ' hoạt động chính xác như nó cho 'List '. –

4

Trước:

foreach(Customer c in Customers) 
{ 
    foreach(Order o in c.Orders) 
    { 
    o.Dance(); 
    } 
} 

Sau:

foreach(Order o in Customers.SelectMany(c => c.Orders)) 
{ 
    o.Dance(); 
} 
0

Khó mà đưa ra câu trả lời mà không có bất kỳ ngữ cảnh hoặc đoạn mã nào. Tuy nhiên, Martin Fowler có một bài viết thực sự tốt về các vòng tái cấu trúc vào các đường ống LINQ có thể được tìm thấy here (đánh giá cao đây là một câu hỏi cũ, vì vậy hy vọng người đọc trong tương lai sẽ được hưởng lợi!).

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