2010-02-26 14 views
57

Cosa succede se ho cicli annidati e voglio rompere tutti in una volta?Come uscire da più loop contemporaneamente in C#?

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

In PHP, break prende un argomento per il numero di cicli per uscire dalla. Qualcosa del genere può essere fatto in C#?

E qualcosa di orribile, come goto?

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

questa è la sintassi errata per goto. metti la tua etichetta fuori dagli anelli e non mettere pause ovunque. – Jimmy

+1

Duplicato: http://stackoverflow.com/questions/1586932/what-is-a-neat-way-of-breaking-out-of-many-for-loops-at-once – Foole

+1

Considera: http: // blogs .msdn.com/ericlippert/archive/2010/01/11/continuous-to-an-outer-loop.aspx –

risposta

73

estrarre i cicli annidati in una funzione e quindi è possibile utilizzare il ritorno per uscire dal giro da qualsiasi luogo, piuttosto che rottura.

+15

che è un hack, non è per quello che funzioni, la maggior parte delle persone che odiano goto considerano i ritorni anticipati nelle funzioni altrettanto cattive. Non sono d'accordo con affermazioni così ampie, ma direi che l'uso di goto è altrettanto valido di questa soluzione al problema, sebbene non altrettanto accurato. – matt

+20

Non sono d'accordo completamente opaco. Il numero di persone che credono nel richiedere una singola uscita dalle funzioni è molto più piccolo di coloro che odiano il gotos. Il motivo è che in molte lingue goto non esegue una corretta pulizia delle risorse (non so di certo su C#), ma restituisce. Anche le funzioni IMHO sono per il raggruppamento, l'ambito e la semplificazione del codice correlato. Questo è esattamente ciò che fa. –

+0

Sono d'accordo con questa risposta. Una ragione per mettere i cicli nidificati in una funzione separata è che la funzione originale sta diventando troppo grande. Se la funzione originale è così grande, i loop nidificati sono un buon posto per suddividere la funzione in due funzioni. Hai un'attività A che è una serie di cicli nidificati, quindi vuoi andare all'attività B dopo che i loop hanno trovato quello che stanno cercando.Se ritieni che avere più ritorni sia un problema, è un segno che la tua funzione è troppo grande. –

21

Goto è orribile solo se abusato. Per abbandonare il ciclo più interno di alcuni nidi è accettabile. MA ... bisogna chiedersi perché ci sia così tanto nidificazione in primo luogo.

Risposta breve: No.

+12

+1. Fondamentalmente, ogni struttura di controllo è 'goto' sotto; appena adattato a uno scopo specifico. Per tutto ciò che * non è * coperto da quegli scopi speciali non c'è altra opzione "elegante" di 'goto'. – Joey

+1

IMO GOTO è solo orribile quando viene utilizzato al di fuori della programmazione di assemblaggio. Ad ognuno il suo, però :) – Pwninstein

+0

Dal punto di vista della programmazione strutturata, goto è solo un costrutto di basso livello su cui sono implementati i costrutti di alto livello di selezione e iterazione. Restituisci, interrompi e continua a rompere il modulo di programmazione strutturata e sono effettivamente solo casi speciali di goto, ma nondimeno penso che l'utilità di essi tenda a vincere la giornata. – Stewart

54

Introduci un altro flag di controllo e inseriscilo in tutte le tue nidificazioni mentre le condizioni sono le seguenti. sostituisce anche la (vera) condizione, mentre si ha con quel

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

+1 Molto bello! :) Ho pubblicato qualcosa di simile a questo, ma il tuo era migliore, quindi l'ho cancellato. – Pwninstein

+0

Vorrei poter votare per questo più di una volta. 'If (timeToStop && keepLooping)' può probabilmente perdere la parte 'keepLooping', a parte questo, geniale! – Pwninstein

+1

Non capisco, com'è più facile leggere di goto? devi trovare un nome variabile che descriva l'intenzione di farlo uscire da tutti i loop, perché non ti limiti a creare un nome per un'etichetta goto? dopo tutto è più lento. devi cercare ovunque che si utilizzi KeepLooking, non solo un'etichetta. – matt

2

Se si vuole uscire da un intero metodo, quindi utilizzare il codice qui sotto. Se si vuole uscire da una serie di loop all'interno di un metodo senza uscire dal metodo, allora una delle risposte che sono già state pubblicate farà il lavoro.

if (TimeToStop) 
{ 
    return; 
}