Pregunta

Tengo algo de código que se estructura como la siguiente:

if (someStatement)
{
    //...
    if (SomeOtherStatement)
    {
        //..., possibly more cases like this
    }
    else
    {
        //goto warning;
        //would otherwise repeat
        //the MessageBox.Show here
    }
}
else
{
    //goto warning;
}
//...
warning:
MessageBox.Show("some warning");

A medida que aborrezco código copiado, es ésta una de las pocas aplicaciones útiles de Goto o hay una mejor estructura que pueda usar?

¿Fue útil?

Solución

¿Qué hay de esto?

if (someStatement)
{
    //...
    if (SomeOtherStatement)
    {
        //..., possibly more cases like this

        return; // in the inner-most case
    }
}

MessageBox.Show("some warning");

Otros consejos

Sí, pero sólo si por goto que quiere decir "crear una función y llamarla varias veces".

el mejor enfoque depende de lo que el resto de su código es el siguiente. si el código que se muestra es el último código en ese método:

if(someStatement) {
    // ...
    if(SomeOtherStatement)
    {
        // a couple of lines of code
        return; // !
    }
}

MessageBox.Show("someWarning");

Si no es así, es probable que tenga a replicar a algo como esto:

if(someStatement) {
    // ...
    if(SomeOtherStatement)
    {
        // a couple of lines of code
    }
    else 
    {
        showWarning("not someOtherStatement");
    }
}
else
{
    showWarning("not someStatement");
}

Yo personalmente considero el manejo de errores centralizado como "casi el único caso", donde Goto es aceptable. Sin embargo, para una mejor estructura, yo pondría la etiqueta totalmente fuera de la otra, al final de su función.

¿Está mostrando el mismo mensaje de error en ambas líneas? Entonces usted debe escribir una función que llama simplemente esa línea y llamar a esa función en ambas ocasiones.

if (someStatement)
{
    //...
    if (SomeOtherStatement)
    {
        //..., possibly more cases like this
    }
    else
    {
        showError();
    }
}
else
{
    showError();
}

Por cierto: este es un mal ejemplo, se puede resolver con una sola cosa-rama para controlar el error. Aquí está uno mejor:

if (!doSomething())
{
    showError();
}
doSomethingElse();
if (!anotherCall())
{
    showError();
}

Si se van a poner en una declaración de la prueba de error desagradable profundo como es así, entonces es posible que desee considerar envolviéndolo con un solo try / catch, y lanzar la aplicación apropiada excepciones específicas dentro de la sentencia if, y la captura esas excepciones específicas en el bloque catch, dejando que todos los otros van a ser capturados más arriba en la cadena.

Las excepciones son la forma correcta de manejar los errores en .NET, tirarlos, pero usarlos con sabiduría:

try
{
    if (someStatement)
    {
        //...
        if (SomeOtherStatement)
        {
            //..., possibly more cases like this
        }
        else
        {
            throw new MyException();
            //would otherwise repeat
            //the MessageBox.Show here
        }
    }
}
catch(MyException e)
{
    MessageBox.Show(e.Message);
    // log the exception, if necessary
}
finally
{
    // tidy up
}

Con la excepción se obtiene una respuesta inflexible de tipos a lo que salió mal, que se puede implementar fácilmente en los sistemas de registro.

Desde (comenzando con el marco 1.1) lógico-y "&&": "sólo evalúa su segundo operando si es necesario."

¿Qué hay de malo en:

if(someStatement && someOtherStatement)
{
       // more whatever
}
else
{
       // raise an exception, call a method, show messagebox, whatever
}

En función de la complejidad de la evaluación lógica pasa si la primera cláusula se evalúa como verdadero; y que, posiblemente, poner en práctica un montón de otras pruebas, cualquier número de los que podría dar lugar a errores : todos los cuales que desea que se manejan en la forma idéntica: lo consideraría obligatoria a cualquiera de levantar una excepción específica, llama a un método para controlar el error, o poner todo en un bloque try-catch (que puede ser bastante feo si hay mucho de código).

Un método usaría si era una presunción razonable de que la posibilidad de error era bastante remota 99% del tiempo, el código se llama baja hacia abajo-sucia-astuto: Me puse una bandera booleana para reflejar un error estado: evaluar que al finalizar el bloque de código complejo, y hacer lo que había que hacer: por supuesto si sus ramas de código en alguna parte como resultado de estas evaluaciones internas : que no sería una buena cosa .

Creo Goto es una mala idea. Si usted tiene que saltar, lanzar una excepción, según lo propuesto por joshcomley; si sólo desea que el mensaje de advertencia, pero continúa sin un salto, llamar a un método.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top