2009-10-14 28 views
13

Me preguntaba por qué C# me exige utilizar break en una declaración switch, aunque una semántica fallida por definición no está permitida. por lo tanto, el compilador podría generar el break al final de cada case -block y guardarme la molestia.¿Por qué necesito usar break?

Sin embargo, hay un escenario (que ya ha sido discutido en este sitio) que podría llegar a esa podría ser la razón para el uso explícito de break:

switch (foo) { 
    case 0: 
    case 1: 
     bar(); 
     break; 
    default: 
     break; 
} 

En este caso, el método bar() se llama si foo tiene el valor 0 o 1.

Esta opción se rompería en el verdadero sentido de la palabra si el compilador generara break enunciados por sí mismo. ¿Es este el motivo por el cual el descanso es obligatorio o hay otras buenas razones?

+7

Personalmente, creo que esta fue una decisión de diseño horrible por parte del equipo de C# y uno de los pocos lugares donde fallaron. –

+0

@Chris: Le recomiendo que lea el blog de Eric como está vinculado en la respuesta aceptada. Aborda varias cosas que supongo que son cosas que te han molestado. –

+3

¿Y cómo lo hubieras hecho, Chris? –

Respuesta

33

Sospecho que la razón por la que C# requiere que el desarrollador coloque un break o una instrucción de terminal al final de cada caso es para mayor claridad.

Evita que los recién llegados al lenguaje asuman que el interruptor() en C# se comporta como el interruptor en C o C++ donde ocurre el comportamiento fallido. Solo en los casos de cajas vacías adyacentes que se producen se producen en C#, lo cual es relativamente obvio.

EDITAR: En realidad, en C# Fallthrough siempre es ilegal. Lo que es legal, sin embargo, es tener un solo caso asociado con dos o más etiquetas. Eric Lippert writes at length about this comportamiento and how it differs from C/C++ switch statements.

Le puede interesar leer this article en el blog de Eric Lipperts.

+0

+1 para el enlace a Eric Lippert, er, blog ;-). Sí, podría ser la claridad lo que impulsó esta decisión de diseño. –

+0

También permite la flexibilidad de JIT para reorganizar el código para optimizaciones sin preocuparse por romper algo debido a la caída. –

+0

@ScottDorman - No hay ningún fracaso ... por lo que la reorganización no cambiaría nada si el descanso no tenía que estar allí. Si hubo una caída, y el reordenamiento del código podría causar un problema, entonces la ruptura no se requeriría de todos modos. – RHSeeger

0

Mi comprensión del asunto es que se incluyó para que coincida con la sintaxis de C++.

+6

Hm, pero AFAIK C++ no requiere la declaración de interrupción porque C++, como C, permite bloques de casos caerse. –

6

Al hacer pausa opcional, se abre la puerta a los errores de la siguiente manera:

switch (thing_result) 
{ 
    case GOOD_THING: 
     IssueReward(); 
     // UH-OH, missing break! 
    case BAD_THING: 
     IssuePunishment(); 
     break; 
} 

Los diseñadores del lenguaje C# han tratado de ayudar a los programadores a evitar errores en los idiomas en los que había antes de él, en general, al obligar al programador ser más explícito (por ejemplo, uso explícito de la palabra clave 'anular' o 'nueva' para implementar o sombrear miembros virtuales).

0

Si usted no necesitaría para anexar un descanso, hay un problema

switch (number) 
{ 
    case 0: 
    case 1: 
     DoSomething(); 
} 

¿Qué ocurre si el número == 0? ¿Es esto un caso vacío que no hace nada o se ejecutará DoSomething()?

+1

Lo siento, pero eso no es cierto. Cuando agrega un descanso después de la llamada DoSomething(), el código C# sería válido y para ambos casos, 0 y 1, se llamaría al método DoSomething(). –

+1

@RHSeeger, estás equivocado. – Phong

+0

@Phong, eliminé mi comentario porque parte de eso era correcto. Era correcto que la declaración de interrupción solo agrega verbosidad y no evita confusiones. Pero fue incorrecto porque el caso 0 hace algo, lo que hace el caso 1 ... ya que comparte el cuerpo con el caso 1. – RHSeeger

38

La pregunta presupone una falsedad y, por lo tanto, no se puede responder. El idioma NO requiere un descanso al final de una sección de interruptor. El lenguaje requiere que la lista de instrucciones de una sección de conmutadores debe tener un punto final inalcanzable. "break" es solo la declaración más comúnmente utilizada que tiene esta propiedad. Es perfectamente legal finalizar una sección de cambio con "return", "goto case 2;", "throw new Exception()"; o "while (true) {}" (o en algunos casos, continúe, aunque eso suele ser una mala idea)

El motivo por el que necesitamos una lista de instrucciones con un punto final inalcanzable es aplicar la regla "no fall through" .

Si su pregunta se expresa mejor como "¿por qué el compilador no repara automáticamente mi error cuando no puedo generar una sección de conmutación con una lista de instrucciones con un punto final inalcanzable al insertar una declaración de interrupción en mi nombre?" , entonces la respuesta es que C# no es una "suposición acerca de lo que el desarrollador probablemente quiso decir y se entretuvo" tipo de lenguaje. Algunos lenguajes son - JScript, por ejemplo - pero C# no lo es.

Creemos que los programadores de C# que cometen errores quieren que se les informe acerca de esos errores para que puedan corregirlos de manera intencional y deliberada, y que esto es algo bueno. Nuestros clientes nos dicen que no quieren que el compilador adivine qué significan y esperan lo mejor. Es por eso que C# tampoco adivina dónde quería colocar el punto y coma faltante, como hace JScript, o falla silenciosamente cuando intenta modificar una variable de solo lectura, como hace JScript, y así sucesivamente.

+4

?? La respuesta aceptada se refiere al blog de Eric y su propia respuesta se ve perjudicada? Lo votó de nuevo. – SolutionYogi

+1

Bueno, SolutionYogi, no todos están de acuerdo conmigo. No tengo ninguna razón para imaginar que todos lo harían; todos tienen derecho a su propia opinión sobre por qué el lenguaje fue diseñado tal como era. Aprecio el gesto, pero realmente, no te preocupes por eso. :) –

+0

Bueno, Eric, estoy de acuerdo contigo al 100% y quiero participar con mi voto para que otros presten atención a tu respuesta! Y no estoy estresando por eso. Yo religiosamente sigo tus respuestas/comentarios mientras aprendo mucho de ellos. No solo está muy bien informado, sino que comparte su conocimiento a través de su escritura impecable. Soy un gran admirador suyo y cada vez que se encuentre en NJ/NY, hágamelo saber, me gustaría comprarle bebidas/cena. :) – SolutionYogi

Cuestiones relacionadas