2010-02-26 9 views
57

Nếu tôi có vòng lặp lồng nhau và tôi muốn thoát ra khỏi tất cả chúng cùng một lúc thì sao?Làm thế nào để thoát ra khỏi nhiều vòng cùng một lúc trong C#?

while (true) { 
    // ... 
    while (shouldCont) { 
     // ... 
     while (shouldGo) { 
      // ... 
      if (timeToStop) { 
       break; // Break out of everything? 
      } 
     } 
    } 
} 

Trong PHP, break lấy lý lẽ cho số vòng lặp thoát ra. Có thể một cái gì đó như thế này được thực hiện trong C#?

Còn điều gì đó ghê gớm, như goto?

// In the innermost loop 
goto BREAK 
// ... 
BREAK: break; break; break; 
+0

đó là cú pháp sai cho goto. chỉ cần đặt nhãn của bạn bên ngoài các vòng và không đặt bất kỳ phá vỡ bất cứ nơi nào. – Jimmy

+1

Trùng lặp: http://stackoverflow.com/questions/1586932/what-is-a-neat-way-of-breaking-out-of-many-for-loops-at-once – Foole

+1

Cân nhắc: http: // blog .msdn.com/ericlippert/archive/2010/01/11/continue-to-an-outer-loop.aspx –

Trả lời

73

Extract vòng lồng nhau của bạn thành một chức năng và sau đó bạn có thể sử dụng lợi nhuận để có được ra khỏi vòng lặp từ bất cứ nơi nào, chứ không phải là phá vỡ.

+15

đó là một hack, không phải là chức năng cho, hầu hết những người ghét goto xem xét lợi nhuận sớm trong các chức năng cũng như xấu. Tôi không đồng ý với những phát biểu rộng lớn như vậy, nhưng tôi sẽ nói rằng việc sử dụng goto chỉ là hợp lệ như giải pháp này cho vấn đề, mặc dù chắc chắn không phải là gọn gàng. – matt

+20

Tôi không đồng ý hoàn toàn mờ. Số lượng người tin rằng yêu cầu một lối ra duy nhất từ ​​chức năng là _much_ nhỏ hơn những người ghét gotos. Lý do là trong nhiều ngôn ngữ goto không thực hiện dọn dẹp tài nguyên chính xác (không biết về C# cho chắc chắn) nhưng trở lại không. Ngoài ra chức năng IMHO là để nhóm, phạm vi và đơn giản hóa mã có liên quan. Đó chính xác là điều này. –

+0

Tôi đồng ý với câu trả lời này. Một lý do để đặt các vòng lồng nhau vào một hàm riêng biệt là hàm ban đầu đang trở nên quá lớn. Nếu hàm ban đầu là lớn, các vòng lặp lồng nhau là một nơi tốt để phá vỡ hàm thành hai hàm. Bạn có nhiệm vụ A là một loạt các vòng lặp lồng nhau, sau đó bạn muốn đi đến nhiệm vụ B sau khi các vòng lặp đã tìm thấy những gì họ đang tìm kiếm.Nếu bạn cảm thấy có nhiều lợi nhuận là một vấn đề, đó là dấu hiệu hàm của bạn quá lớn. –

21

Goto chỉ ẩn khi bị lạm dụng. Để thả ra khỏi vòng lặp trong cùng của một số lồng nó có thể chấp nhận được. NHƯNG ... người ta phải hỏi tại sao có rất nhiều làm tổ ở đó ngay từ đầu.

Câu trả lời ngắn: Số

+12

+1. Về cơ bản, mọi cấu trúc điều khiển là 'goto' bên dưới; chỉ được lắp vào một mục đích cụ thể. Đối với tất cả mọi thứ mà * không * được bao phủ bởi những mục đích đặc biệt đó thì không có tùy chọn “thanh lịch” nào khác ngoài 'goto'. – Joey

+1

IMO GOTO chỉ ẩn khi được sử dụng ngoài lập trình lắp ráp. Tuy nhiên, đối với từng điểm riêng của mình: – Pwninstein

+0

Từ quan điểm lập trình có cấu trúc, goto chỉ là một cấu trúc cấp thấp mà trên đó các cấu trúc lựa chọn và lặp lại cao cấp được thực hiện. Quay trở lại, phá vỡ và tiếp tục phá vỡ các mô-đun lập trình có cấu trúc và có hiệu quả chỉ là trường hợp đặc biệt của goto, nhưng dù sao tôi nghĩ rằng sự hữu ích của họ có xu hướng giành chiến thắng trong ngày. – Stewart

54

Giới thiệu một cờ điều khiển khác và đặt nó vào tất cả các lồng nhau trong khi điều kiện như dưới đây. Ngoài ra, hãy thay thế điều kiện trong khi (đúng) bạn có với điều đó

bool keepLooping = true; 
while (keepLooping) { 
    // ... 
    while (shouldCont && keepLooping) { 
     // ... 
     while (shouldGo && keepLooping) { 
      // ... 
      if (timeToStop) { 
       keepLooping = false; 
       break; // break out of everything? 
      } 
     } 
    } 
} 
+2

+1 Rất đẹp! :) Tôi đăng một cái gì đó loại tương tự như thế này, nhưng bạn đã tốt hơn, vì vậy tôi đã xóa nó. – Pwninstein

+0

Tôi ước tôi có thể bỏ phiếu cho điều này nhiều lần. 'If (timeToStop && keepLooping)' có thể có thể mất phần 'keepLooping', khác hơn thế, rực rỡ! – Pwninstein

+1

Tôi không hiểu, cách này dễ đọc hơn goto như thế nào? bạn phải đưa ra một tên biến mô tả ý định của nó để thoát ra khỏi tất cả các vòng, tại sao bạn không đặt cùng một nỗ lực để đưa ra một cái tên cho một nhãn goto? điều này là sau khi tất cả chậm hơn. bạn phải tìm ở khắp mọi nơi mà keepLooking được sử dụng, không chỉ là một nhãn. – matt

2

Nếu bạn muốn thoát ra khỏi toàn bộ phương pháp, hãy sử dụng mã bên dưới. Nếu bạn chỉ muốn thoát ra khỏi một loạt các vòng trong một phương pháp mà không vi phạm phương pháp, thì một trong những câu trả lời đã được đăng sẽ thực hiện công việc.

if (TimeToStop) 
{ 
    return; 
}