2010-12-14 27 views
13

Kể từ foreach() phương pháp lặp qua tất cả một thành viên danh sách, Tại sao không thể sử dụng một break /tiếp tục khoản trong khi tôi có thể sử dụng chúng trong một vòng lặp foreach bình thườngforeach(): Tại sao không thể sử dụng break/tiếp tục bên

lstTemp.ForEach(i=> 
{ 
    if (i == 3) 
    break; 
    //do sth 
} 
); 

Lỗi:

"No enclosing loop out of which to break or continue"

+0

Một phần mở rộng ForEach cũng bằng văn bản nên cho phép bạn trả về false nếu bạn muốn nó để phá vỡ. Nhưng tôi không thể nói chắc chắn vì tôi không biết bạn đã kiếm tiền từ đâu. Nếu bạn tự viết nó, đó có thể là một lựa chọn tốt. – Tesserex

+0

Có vẻ như bạn muốn hàm TakeWhile http://msdn.microsoft.com/en-us/library/bb534804%28v=VS.90%29.aspx – Juliet

+0

Tôi tìm thấy câu trả lời hay hơn tại đây: http://stackoverflow.com/questions/3145563/list-foreach-break –

Trả lời

18

ForEach là phương thức chứ không phải là vòng lặp foreach thông thường. Phương pháp ForEach có sẵn cho các tác vụ đơn giản, nếu bạn cần phá vỡ hoặc tiếp tục chỉ cần lặp lại qua lstTemp với vòng lặp foreach thông thường.

Thông thường, ForEach được thực hiện như thế này:

public static ForEach<T>(this IEnumerable<T> input, Action<T> action) 
{ 
    foreach(var i in input) 
    action(i); 
} 

Vì nó là một phương pháp gọi bình thường, action không biết gì về kèm theo foreach, do đó bạn không thể phá vỡ.

+0

Cho rằng đó là một cuộc gọi phương thức, tôi có thể quay lại thay vì nghỉ không? – Lance

+0

Không, bạn sẽ chỉ trở về từ chính phương thức đó. Bạn sẽ không thể thoát ra khỏi một cuộc xâm lược bên ngoài theo cách đó. – Femaref

17

có lẽ bởi vì bạn đang sử dụng một lambda và các nội dung của lambda là ngu dốt đến thực tế là nó đang được sử dụng bên trong một vòng lặp.

2

ngắt và tiếp tục là các từ khóa ngôn ngữ C# yêu cầu hỗ trợ trình biên dịch. ForEach, với trình biên dịch C#, chỉ là một phương thức.

4

Cách tôi giải thích điều này là: ForEach là phương pháp , không phải là tính năng ngôn ngữ . Cấu trúc C# foreach là một tính năng của ngôn ngữ mà ngôn ngữ khác xây dựng breakcontinue được phép. Tôi cũng sẽ chỉ ra (không cố gắng phán xét, chỉ cần quan sát) rằng đây là một ví dụ tốt về lý do tại sao một số nhà phát triển phản đối việc sử dụng phương pháp ForEach: nó không thực sự tiết kiệm được gõ trong trường hợp đơn giản này , nó đòi hỏi một chuyển hướng nhiều hơn cần thiết, và nó không có tất cả các chức năng của foreach anyway.

Theo tôi, kịch bản chính trong đó phương thức ForEach có ý nghĩa như một phần mở rộng trên IEnumerable<T> - để đặt ở cuối chuỗi cuộc gọi phương thức. Có vẻ như (đối với tôi) có chút lạ lùng khi họ thêm nó vào List<T>.

0

Vì bạn ủy thác một hành động cho từng mục trong danh sách.

10

hơn là sử dụng một đột phá, thực hiện một bộ lọc đầu tiên như thế này (nó có thể không phải là bộ lọc chính xác mà bạn cần, nhưng minh họa điểm)

lstTemp.Where(i => i!= 3).ForEach(i=> // do sth); 
+0

-1 Không phải là sự lấy mẫu. mã của bạn sẽ chạy cho mọi i! = 3. Mã được trình bày sẽ chạy cho đến i == 3. – Sergio

+0

Đây có vẻ là cách tốt nhất để 'tiếp tục'. Bên cạnh đó chúng ta chỉ có thể viết 'return' cho 'break'. – Nigiri

0

Bạn có thể viết một phương pháp mở rộng "ForEachWhile" mà sẽ đưa a Function<T, bool> và dừng khi sai.

5

Để lặp chỉ là một phần của các mặt hàng và bắt chước giờ nghỉ một cách hoàn hảo, bạn có thể sử dụng FirstOrDefault:

lstTemp.FirstOrDefault(i=> 
{ 
    if (i == 3) 
     return true; 

    //do stuff 

    return false; 
} 
); 

Đối với danh sách với 100000 mục, nếu mục 10 là 3 nó sẽ lặp chỉ 10 lần, bằng cách sử dụng Giải pháp Where sẽ hoạt động, nhưng trước tiên hãy lặp lại toàn bộ danh sách.

+1

Phương thức 'Where' không lặp lại bộ sưu tập, xem: hoãn thi hành. –

+0

@ James có thể * lặp * không phải là từ đúng .. nhưng để tìm tất cả các mục phù hợp, một nơi nào đó tất cả các mục phải được kiểm tra, phải không? –

+1

Hãy đọc từ khóa 'yield' hoạt động như thế nào, vì đó là cách các truy vấn LINQ hoạt động. Quá dài để giải thích ở đây, nhưng không, không phải tất cả các mục phải được kiểm tra; chỉ có nhiều mục được yêu cầu bởi chuỗi cuộc gọi sẽ được kiểm tra. Chính xác giống như 'FirstOrDefault' của bạn, nó sẽ lặp lại cho đến khi nó chạm vào một trận đấu. –

-1

i sử dụng nó

 list.ForEach((item) => 
     { 
      if(isBreak == false) do 
      { 
       if (isContinue) 
        break; 

       // TODO 
      } while (false); } 
     }); 
+0

điều này không chính xác trả lời câu hỏi. OP hỏi tại sao anh/cô ấy không thể sử dụng break/continue như một vòng lặp bình thường. – Rafael

+0

Thử xóa 'do-while' và sử dụng' break', LOL. – code4life

3

return sẽ hoạt động như continue trong ForEach.

Ví dụ:

var list = new List<int>() {1, 2, 3, 4}; 
list.ForEach(i => 
    { 
     if (i == 3) 
      return; 
     Console.WriteLine(i); 
    } 
); 

Prints 1, 2, 4.

3 - bỏ qua.

1

Bởi vì ForEach là một phương pháp và không phải là vòng lặp foreach thông thường cần lặp qua lstTemp với vòng lặp foreach thường xuyên trong trường hợp ngắt, nhưng trong trường hợp tiếp tục sử dụng trở lại bên trong phương thức ForEach.

var lstTemp = new List<int>() {1, 2, 3, 4}; 
lstTemp.ForEach(i=> 
{ 
    if (i == 3) return; 
    //do sth 
    Console.WriteLine(i); 
}); 

Output: 1, 2, 4

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