165 votos

¿Por qué no utilizar excepciones como flujo regular de control?

Mi pregunta se reduce a : "¿por Qué no utilizar excepción (o de error para el caso) de control para regular el flujo de un programa? Para evitar todas las respuestas que me podría haber buscado en google, voy a poner un ejemplo que todos pueden atacar a voluntad.

C# y Java (y muchos otros) cuentan con un montón de tipos de algunos de los 'desbordamiento' comportamiento no me gusta en absoluto. (type.MaxValue + type.SmallestValue == type.MinValue por ejemplo : int.MaxValue + 1 == int.MinValue). Pero, visto mi naturaleza maligna, voy a añadir un insulto a esta lesión e incluso ampliar este comportamiento, digamos que un Anulado de tipo DateTime. (Sé DateTime está sellado .NETO, pero por el bien de este ejemplo, voy a usar un pseudo lenguaje que es exactamente igual que en C#, excepto por el hecho de que la DateTime no está sellado :-))

El método Add :

        /// <summary>
        /// Increments this date with a timespan, but loops when
        /// the maximum value for datetime is exceeded.
        /// </summary>
        /// <param name="ts">The timespan to (try to) add</param>
        /// <returns>The Date, incremented with the given timespan. 
        /// If DateTime.MaxValue is exceeded, the sum wil 'overflow' and 
        /// continue from DateTime.MinValue. 
        /// </returns>
        public DateTime override Add(TimeSpan ts) 
        {
            try
            {                
                return base.Add(ts);
            }
            catch (ArgumentOutOfRangeException nb)
            {
                // calculate how much the MaxValue is exceeded
                // regular program flow
                TimeSpan saldo = ts - (base.MaxValue - this);
                return DateTime.MinValue.Add(saldo)                 		
            }
            catch(Exception anyOther) 
            {
                // 'real' exception handling.
            }
        }

Por supuesto, un caso puede resolver este tan fácil, pero el hecho sigue siendo que yo no veo por qué no se puede utilizar excepciones (lógicamente, es decir, que se puede ver que cuando el rendimiento es un problema que, en ciertos casos, las excepciones deben ser evitadas). Creo que en muchos casos están más claro que si-estructuras y no se rompen cualquier contrato el método que se está haciendo.

En mi humilde opinión, El "no usarlas Nunca para regular el flujo del programa"la reacción de todo el mundo parece tener no es que así como el sótano la fuerza de reacción que puede justificar.

O estoy equivocada?

He leído otros mensajes, el trato con todo tipo de casos especiales, pero mi punto es : si usted es de 1. Claro y 2. Hounour el contrato de su método,

no hay nada de malo con ello. Shoot me.

149voto

Brann Puntos 9983

¿Alguna vez has tratado de depurar un programa de sensibilización cinco excepciones por segundo en el curso normal de la operación ?

Que tengo.

El programa era bastante complejo (fue distribuida servidor de cálculo), y una ligera modificación en uno de los laterales del programa podría fácilmente romper algo totalmente diferente.

Ojalá pudiera haber puesto en marcha el programa y espere a que las excepciones a ocurrir, pero había alrededor de 200 de las excepciones durante la fase de inicio en el curso normal de las operaciones

Mi punto : si el uso de excepciones para situaciones normales, ¿cómo se puede localizar inusual (es decir, la excepciónal) situaciones ?

Por supuesto, hay otras razones de peso para no usar excepciones demasiado, especialmente en cuanto al rendimiento

142voto

Anton Gogolev Puntos 59794

Las excepciones son, básicamente, la no-local goto declaraciones con todas las consecuencias de este último. Mediante el uso de excepciones para el control de flujo infringe el principio de la menor sorpresa, hacer programas difíciles de leer (recuerde que los programas están escritos para que los programadores de primera).

Por otra parte, esto no es lo que el compilador de vendedores esperan. Ellos esperan que las excepciones se inicien rara vez, y por lo general vamos a la throw código de ser bastante ineficiente. Lanzar excepciones es uno de los más caros de operaciones .NETO.

Sin embargo, algunos idiomas (en particular de Python) uso de excepciones de control de flujo de construcciones. Por ejemplo, los iteradores aumentar un StopIteration excepción si no hay más elementos. Incluso estándar de construcciones del lenguaje (como for) se basan en este.

23voto

cwap Puntos 6098

Mi regla de oro es:

  • Si usted puede hacer algo para recuperarse de un error, la captura de excepciones
  • Si el error es muy común (ej. usuario ha intentado iniciar sesión con una contraseña incorrecta), el uso de returnvalues
  • Si usted no puede hacer nada para recuperarse de un error, dejo dicho (O captura en su principal punto de atracción para hacer algunos semi-apagado ordenado de la aplicación)

El problema que yo veo con las excepciones es desde una perspectiva puramente sintaxis de punto de vista (estoy bastante seguro de que el rendimiento de la carga es mínima). No me gusta tratar de bloques por todo el lugar.

Tomemos este ejemplo:

try
{
   DoSomeMethod();  //Can throw Exception1
   DoSomeOtherMethod();  //Can throw Exception1 and Exception2
}
catch(Exception1)
{
   //Okay something messed up, but is it SomeMethod or SomeOtherMethod?
}

.. Otro ejemplo podría ser cuando usted necesita para asignar algo a un mango, el uso de una fábrica, y que la fábrica podría lanzar una excepción:

Class1 myInstance;
try
{
   myInstance = Class1Factory.Build();
}
catch(SomeException)
{
   // Couldn't instantiate class, do something else..
}
myInstance.BestMethodEver();   // Will throw a compile-time error, saying that myInstance is uninitalized, which it potentially is.. :(

Soo, personalmente, creo que se debe mantener excepciones raras error-condiciones (de la memoria, etc.) y el uso returnvalues (valueclasses, estructuras o las enumeraciones) para su comprobación de errores en su lugar.

Esperanza entendí tu pregunta correcta :)

21voto

Peter Puntos 14647

Una primera reacción a una gran cantidad de respuestas :

está escrito para los programadores y el principio de la menor sorpresa

¡Por supuesto! Pero si sólo isnot más claro todo el tiempo.

No debería ser sorprendente , por ejemplo : la brecha (1/x) catch (divisionByZero) es más claro que cualquier si a mí (en el Conrad y otros) . El hecho de que este tipo de programación no se espera es puramente convencional, y de hecho, sigue siendo relevante. Tal vez en mi ejemplo, si sería más clara.

Pero DivisionByZero y FileNotFound para que el asunto está más claro que el ifs.

Por supuesto, si es menos eficiente y necesaria de un trillón de tiempo por segundo, usted debe, por supuesto, evitar, pero todavía no he leído ninguna buena razón para evitar la valoracion de diseño.

En cuanto al principio de la menor sorpresa : hay un peligro de razonamiento circular aquí : supongamos que una a toda la comunidad, utiliza un mal diseño, este diseño se convertirá en espera! Por lo tanto, el principio no puede ser un grial y debe ser considerado como cuidadosamente.

excepciones para situaciones normales, ¿cómo se puede localizar inusual (es decir, excepcional) situaciones ?

En muchas de las reacciones de la sth. como este brilla comedero. Sólo coger, no? Su método debe ser clara, bien documentado, y hounouring es contrato. No entiendo esa pregunta, debo admitir.

La depuración de todas las excepciones : el mismo que acaba de hacer, a veces, debido a que el diseño no utilizar excepciones es común. Mi pregunta era : ¿por qué es común en el primer lugar?

11voto

mouviciel Puntos 36624

El estándar de la respuesta es que las excepciones no son regulares y se debe utilizar en casos excepcionales.

Una razón, que es importante para mí, es que cuando he leído try-catch estructura de control en un software que mantener o depuración, yo trate de averiguar por qué el original programador utiliza un tratamiento de excepción en lugar de un if-else estructura. Y espero encontrar una buena respuesta.

Recuerde que escribir el código, no sólo para el equipo sino también para otros programadores. Hay una semántica asociada a un controlador de excepciones que usted no puede tirar solo porque la máquina no la mente.

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by: