c# - switch - ejemplos de goto en lenguaje c
¿Alguien todavía usa[goto] en C#y si es así por qué? (10)
El compilador usa declaraciones goto
en varias partes del código generado, por ejemplo, en los tipos de bloque de iterador generados (generados al usar la palabra clave yield return
). Estoy bastante seguro de que los tipos de serialización XML generados también tienen algunas declaraciones goto
allí también.
Consulte los detalles de implementación del bloque Iterator: máquinas de estado generadas automáticamente para obtener más detalles sobre por qué / cómo el compilador de C # maneja esto.
Aparte del código generado, no hay una buena razón para usar una instrucción goto
en el código normal: hace que el código sea más difícil de entender y, como resultado, es más propenso a errores. Por otro lado, usar declaraciones goto
en código generado como este puede simplificar el proceso de generación y normalmente está bien porque nadie va a leer (o modificar) el código generado y no hay posibilidad de que se cometan errores porque una máquina está escribiendo .
Consulte la declaración Ir a Considerar perjudicial para un argumento contra goto
, así como una pieza clásica de la historia de programación.
Me preguntaba si alguien todavía usa la sintaxis de la palabra clave "goto" en C # y cuáles son las posibles razones para hacerlo.
Tiendo a ver cualquier declaración que haga que el lector salte el código como una mala práctica, pero me pregunto si hubo escenarios creíbles para usar tal sintaxis.
El procesador implementa al menos una instrucción de salto y estoy seguro de que muchas declaraciones las usan en su implementación o interpretación.
Una de las cosas buenas de usar un lenguaje de 3rd o 4th generación es que estos detalles físicos se abstraen de nosotros. Si bien deberíamos estar atentos a la ley de la abstracción con filtraciones , creo que también deberíamos usar nuestras herramientas como están destinadas (lo siento ). Si estuviera escribiendo código y un goto
parecía una buena idea, sería hora de refactorizar. El propósito de un lenguaje estructurado es evitar estos "saltos" y crear un flujo lógico en nuestra ingeniería.
Debería evitar el uso del break
pero no puedo pasar por alto el beneficio del rendimiento. Sin embargo, si he anidado bucles que necesitan break
mutuamente, es hora de refactorizar.
Si alguien puede proponer un uso de goto
que parece mejor que refactorizar, con mucho gusto retiraré mi respuesta.
Espero no ser culpable de ir corriendo al " cobertizo para bicicletas " aquí. Como dice Kragen, lo que es suficiente para Dijkstra es lo suficientemente bueno para mí.
Es particularmente bueno cuando tiene que limpiar antes de regresar de un método, por ejemplo.
while (stream.Read(buffer, 0, 4) == 4)
{
// do smth with the 4 bytes read here
if (stream.Read(buffer, 0, 4) != 4) goto CLOSE_STREAM_AND_RETURN;
// do more stuff
if (stream.Read(buffer, 0, 4) != 4) goto CLOSE_STREAM_AND_RETURN;
// more stuff
}
CLOSE_STREAM_AND_RETURN:
stream.Close();
Inspirado por: http://eli.thegreenplace.net/2009/04/27/using-goto-for-error-handling-in-c/
Estaba mirando el código fuente .net y encontré this en la propiedad ControlStyle para un WebControl
public Style ControlStyle
{
get
{
if (this.controlStyle == null)
{
this.controlStyle = this.CreateControlStyle();
if (base.IsTrackingViewState)
{
this.controlStyle.TrackViewState();
}
if (!this._webControlFlags[1])
{
goto IL_4D;
}
this._webControlFlags.Clear(1);
this.controlStyle.LoadViewState(null);
}
IL_4D:
return this.controlStyle;
}
}
Entonces, incluso Microsoft lo usa
Goto nunca es mejor. Y continúe, corte (excepto en el interruptor / caja), retorno (múltiple), y tiro también debe mantenerse al mínimo mínimo. Nunca querrá escapar del medio de los bucles nidos. Siempre quiere que las instrucciones de control de bucle tengan todo el control de bucle. La sangría tiene información, y todas estas declaraciones tiran esa información. También podría sacar todas las sangrías.
Hay algunos casos (raros) en que goto puede mejorar la legibilidad. De hecho, la documentación a la que vinculó enumera dos ejemplos:
Un uso común de goto es transferir el control a una etiqueta de caja de interruptor específica o la etiqueta predeterminada en una declaración de interruptor.
La instrucción goto también es útil para salir de los bucles profundamente anidados.
Aquí hay un ejemplo para este último:
for (...) {
for (...) {
...
if (something)
goto end_of_loop;
}
}
end_of_loop:
Por supuesto, hay otras formas de solucionar este problema, como refactorizar el código en una función, usar un bloque ficticio a su alrededor, etc. (consulte esta pregunta para obtener más información). Como nota al margen, los diseñadores de lenguaje de Java decidieron prohibir goto por completo e introducir una declaración de rotura etiquetada en su lugar.
No recuerdo haber usado nunca goto
. Pero tal vez mejora la intención de un bucle para siempre que realmente no desea salir (sin break
, pero aún puede return
o throw
):
forever: {
// ...
goto forever;
}
Por otra parte, un while (true)
simple while (true)
debería ser suficiente ...
Además, podría usarlo en una situación en la que desee que la primera iteración de un ciclo comience en el medio del ciclo: mire here para ver un ejemplo.
Recuerdo esta parte
switch (a)
{
case 3:
b = 7;
// We want to drop through into case 4, but C# doesn''t let us
case 4:
c = 3;
break;
default:
b = 2;
c = 4;
break;
}
Para algo como esto
switch (a)
{
case 3:
b = 7;
goto case 4;
case 4:
c = 3;
break;
default:
b = 2;
c = 4;
break;
}
Referir This
goto es ideal para romper muchos bucles en los que la ruptura no funcionaría bien (por ejemplo, en condiciones de error), y como Kragen dijo que el compilador usa goto para generar instrucciones de conmutación y algunas otras cosas también.