2009-12-01 5 views
17

Si escribo un ciclo for, do o while, ¿es posible salir de esto con la palabra clave return?¿Usar el retorno para salir de un bucle?

Ej:

class BreakTest 
{ 
public static void Main() 
{ 
    for (int i = 1; i <= 100; i++) 
    { 
    if (i == 5) 
     **return;** 
    Console.WriteLine(i); 
    } 
    } 
} 

Sé retorno puede ser utilizado para salir si las declaraciones, así que estoy curioso de este, ya que nunca he probado (y no puede acceder a mi software para escribir el código para probar esta)

+1

El índice 1 se debe a la sangría ... :-) –

+1

He copiado este código de MSDN como estaba. – dotnetdev

+4

Lo sé, fue solo una broma. Comenzar un índice en 1 no está mal, pero hace que algunos desarrolladores tomen involuntariamente. –

Respuesta

40

return saldrá del método actual (Principal en su ejemplo). Use break para salir del bucle.

+0

Esa es la distinción en la que estaba oxidado. Regrese si no hay nada más de interés para ejecutar en el método. – dotnetdev

+1

Para el beneficio de @ dotnetdev: el otro control de bucle (bueno, en general) continúa, lo que detendrá la iteración actual y comenzará el siguiente, donde como break y return sale de esta y de todas las iteraciones. –

+0

Continuar Estoy contento con, lo uso mucho más. Regreso y descanso que no he usado en mucho tiempo. Gracias. – dotnetdev

3

Usted puede hacer esto. Llamar al return; saldrá de Main(). Normalmente, usaría break; para salir del bucle for.

Dicho esto, a menudo se considera una mala práctica tener varias ubicaciones de devolución dentro de una sola función. Muchos desarrolladores prefieren tener una declaración de devolución única (si el método no está declarado con void). Esto puede hacer que el código sea más fácil de seguir, desde un punto de vista comprensible y, por lo tanto, más fácil de mantener y probar.

+0

¡Conozco la sensación de tener muchos puntos de retorno en un solo método! :) – dotnetdev

+4

Y, por el contrario, algunos códigos son más fáciles de leer y mantener si se utilizan declaraciones de devolución en lugar de expresiones condicionales grandes o condicionales anidados múltiples. Hay bastantes de estas reglas religiosas que se aplican ciegamente en lugar de considerar lo que es más legible, mantenible o de rendimiento basado en las necesidades y el contexto del proyecto. (Y valoro que está señalando la existencia de este punto de vista en lugar de prescribirlo, Reed.) –

+0

No creo que esto sea siempre cierto, por ejemplo, puede querer tener declaraciones de retorno dentro de bloques condicionales cerca de la parte superior de una función para regresar temprano en el caso de entradas incorrectas. Sin embargo, tiene razón en que break es la forma correcta de salir de un bucle. –

4

Sin duda puede hacer lo que está pidiendo. Parece que hay 2 campamentos sobre si deberías o no. Hay algunos que dicen que solo debe haber 1 punto de salida de una función. Sugieren que debe usar una variable de marca para registrar que necesita salir (y posiblemente cualquier información que necesite devolver), y luego regresar una vez que haya salido de su ciclo o haya llegado al final de sus árboles if/else .

Personalmente, no tengo ningún problema con los puntos de salida múltiples de una función, siempre que sean simétricos. ¿Qué quiero decir con "simétrico"? Bueno, si voy a regresar desde el interior de un bucle, también quiero regresar al final del bucle (en caso de que nunca llegue a la condición en el bucle que me haría volver temprano). Si estoy dentro de una jerarquía if/else compleja y regreso desde dentro de uno de los casos, entonces debería regresar desde dentro de todos ellos.

Éstos son algunos ejemplos rápidos de lo que prefiero escribir mi código:

public string Search(IEnumerable<string> values) 
    { 
     foreach(string value in values) 
     { 
      if(SomeArbitraryCondition()) 
       return value; 
     } 

     return null; 
    } 

    public int PerformAction() 
    { 
     if (SomeArbitraryCondition()) 
     { 
      if (SomeArbitraryCondition()) 
      { 
       return 1; 
      } 
      else 
      { 
       return 2; 
      } 
     } 
     else 
     { 
      if (SomeArbitraryCondition()) 
      { 
       return 3; 
      } 
      else 
      { 
       return 4; 
      } 
     } 
    } 

Esto no es realmente una regla dura y rápida que he pensado mucho acerca, pero es simplemente la forma en que yo prefiero escribirlo porque me parece más limpio. En algunos casos, tiene más sentido usar una variable de marcador y simplemente regresar en un solo lugar.

public string Search(IEnumerable<string> values) 
    { 
     string found = null; 
     foreach(string value in values) 
     { 
      if(SomeArbitraryCondition()) 
       found = value; 
     } 

     return found; 
    } 

    public int PerformAction() 
    { 
     int state; 
     if (SomeArbitraryCondition()) 
     { 
      if (SomeArbitraryCondition()) 
      { 
       state = 1; 
      } 
      else 
      { 
       state = 2; 
      } 
     } 
     else 
     { 
      if (SomeArbitraryCondition()) 
      { 
       state = 3; 
      } 
      else 
      { 
       state = 4; 
      } 
     } 

     return state; 
    } 
0

forma en respuesta atrasada pero return; saldrá de su método de conjunto (tan fuera de su bucle, también) si su tipo de retorno es nulo. Si no es así, simplemente no compilará a menos que devuelva el tipo de método.

1

Tenga esto en mente:

  1. se puede hacer esto, pero no es recomendable, ya que automáticamente salidas del método actual de ejecución.
  2. No es útil cuando otras instrucciones después del ciclo son obligatorias no importa las condiciones (debido a su comportamiento se indica en el 1er punto).
  3. Puede crear un efecto dominó en su programa, es decir, intentar resolver un error/error/falla da lugar a muchas novedades. Esto hace que la depuración sea un complejo de bits .
Cuestiones relacionadas