2010-02-26 15 views
57

¿Qué sucede si tengo bucles anidados y quiero salir de todos al mismo tiempo?¿Cómo salir de múltiples bucles a la vez en C#?

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

En PHP, break toma un argumento para el número de bucles para salir de. ¿Se puede hacer algo como esto en C#?

¿Qué tal algo horrible, como goto?

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

esa es la sintaxis incorrecta para goto. simplemente coloque su etiqueta fuera de los bucles y no ponga ningún descanso en ninguna parte. – Jimmy

+1

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

+1

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

Respuesta

73

Extracto de sus bucles anidados en una función y luego se puede utilizar de retorno para salir del bucle desde cualquier lugar, en lugar de romperse.

+15

que es un truco, no para qué sirven las funciones, la mayoría de las personas que odian consideran los retornos tempranos en funciones tan malas. No estoy de acuerdo con esas afirmaciones tan amplias, pero diría que usar goto es tan válido como esta solución al problema, aunque ciertamente no tan claro. – matt

+20

No estoy de acuerdo completamente mate. La cantidad de personas que creen que requieren una única salida de las funciones es mucho menor que las que odian a los gotos. La razón es que en muchos idiomas, goto no realiza la limpieza correcta de los recursos (no se conoce C# con seguridad) pero el retorno sí. También las funciones de la IMHO son para agrupar, definir y simplificar el código relacionado. Eso es exactamente lo que hace esto. –

+0

Estoy de acuerdo con esta respuesta. Una razón para colocar los bucles anidados en una función separada es que la función original se está haciendo demasiado grande. Si la función original es así de grande, los bucles anidados son un buen lugar para dividir la función en dos funciones. Usted tiene la tarea A que es una serie de bucles anidados, luego desea ir a la tarea B después de que los bucles hayan encontrado lo que están buscando.Si siente que tener devoluciones múltiples es un problema, es una señal de que su función es demasiado grande. –

21

Goto solo es horrible cuando se abusa. Para abandonar el ciclo interno de algunos anidamientos, es aceptable. PERO ... uno tiene que preguntar por qué hay tanta anidación allí en primer lugar.

Respuesta corta: No.

+12

+1. Básicamente, cada estructura de control es 'goto' debajo; simplemente ajustado a un propósito específico. Para todo lo que * no está * cubierto por esos propósitos especiales, no hay otra opción "elegante" que "goto". – Joey

+1

IMO GOTO solo es horrible cuando se usa fuera de la programación de ensamblaje. Para cada uno, sin embargo :) – Pwninstein

+0

Desde un punto de vista de programación estructurada, goto es solo una construcción de bajo nivel en la que se implementan las construcciones de alto nivel de selección e iteración. Regrese, rompa y continúe rompiendo el módulo de programación estructurado y son efectivamente solo casos especiales de goto, pero aún así creo que la utilidad de ellos tiende a ganar el día. – Stewart

54

Introduzca otra bandera de control y colóquela en todas sus condiciones anidadas como se muestra a continuación. También reemplaza el while (true) condición que tiene con que

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

+1 ¡Muy bonito! :) Publiqué algo similar a esto, pero el tuyo era mejor, así que lo borré. – Pwninstein

+0

Ojalá pudiera votar por esto más de una vez. El 'if (timeToStop && keepLooping)' probablemente puede perder la parte 'keepLooping', aparte de eso, ¡genial! – Pwninstein

+1

No lo entiendo, ¿cómo es esto más fácil de leer que ir? tienes que encontrar un nombre de variable que describa la intención de romper todos los bucles, ¿por qué no pones el mismo esfuerzo en crear un nombre para una etiqueta goto? esto es, después de todo, más lento. tienes que buscar en todas partes donde se usa keepLooking, no solo una etiqueta. – matt

2

Si desea salir de un método completo, a continuación, utilizar el código de abajo. Si solo quiere salir de una serie de bucles dentro de un método sin romper el método, entonces una de las respuestas que ya se han publicado hará el trabajo.

if (TimeToStop) 
{ 
    return; 
} 
Cuestiones relacionadas