2009-06-13 22 views
20

Escribo una clase personalizada en C# y arrojo un par de excepciones si las personas dan las entradas incorrectas en algunos de los métodos. Si se lanza la excepción, ¿se ejecutará alguno de los códigos en el método después del lanzamiento? ¿Tengo que poner un descanso después del lanzamiento, o un lanzamiento siempre abandona el método?¿Tengo que romper después de lanzar la excepción?

+1

Divida esto en tres preguntas. (1) ¿Se ejecutará alguno de los códigos del método después del lanzamiento? SÍ. Si la excepción estaba dentro de un intento, entonces se ejecutará el código dentro de los bloques de captura coincidentes o finalmente el bloque. Si no hay un bloque de prueba, entonces NO. El control se ramifica al bloque de excepción más cercano, captura o (en vb) el filtro de excepción bloquea la pila. –

+2

(2) ¿Debo poner un descanso después del lanzamiento? NO, nunca hagas eso. El punto final de la declaración de tiro no es alcanzable; un lanzamiento es tratado como un goto por el compilador. Una afirmación inmediatamente después de un lanzamiento no es alcanzable y nunca se ejecutará. –

+1

(3) ¿Un lanzamiento siempre sale del método? NO. Si el lanzamiento está en un intento y el intento tiene un bloque de catch correspondiente, entonces el bloque catch puede "comerse" la excepción. Solo si no hay un bloque catch, la excepción hace una actualización no local de la pila de llamadas. –

Respuesta

30

Cuando throw excepción, el siguiente código que se ejecutará es cualquier bloque catch que cubra ese lanzamiento dentro del método (si lo hay) entonces, el finally block (si existe). Puedes intentarlo, try-catch, try-catch-finally o try-finally. Luego, si no se maneja la excepción, se vuelve a lanzar por un bloque catch o no se captura, el control se devuelve al llamador. Por ejemplo, obtendrá "Sí1, Sí2, Sí3" de este código ...

try 
{ 
    Console.WriteLine("Yes1"); 
    throw (new Exception()); 
    Console.WriteLine("No1"); 

} 
catch 
{ 
    Console.WriteLine("Yes2"); 
    throw; 
    Console.WriteLine("No2"); 
} 
finally 
{ 
    Console.WriteLine("Yes3"); 
} 

Console.WriteLine("No3"); 
+0

Esto sería una excepción (poco e) a mi respuesta. Estaba pensando en una Excepción que se usaría en el contexto común y no se usaría como una declaración GOTO. –

+0

@jarrett: Este es exactamente el contexto común, excepto que el tiro está oculto dentro de las llamadas a funciones. – configurator

27

Throw se moverá hacia arriba de la pila, saliendo así del método.

+2

Gracias. Perdón por hacer una pregunta tan básica. – Ross

1

Si ha envuelto su código en un try ... catch ... finally, a continuación, el código bajo Finalmente siempre se ejecutará. Por ejemplo:

Try 
    ' do some stuff here 
    ' Examine user input 
    If user input isn't valid 
     Throw new exception 
Catch 
    Throw ' Just re-throws the same exception 
Finally 
    ' This code will execute, no matter what - exception or not 
End Try 
1

Como acotación al margen a su pregunta real: es posible que desee reconsiderar el uso de excepciones para proporcionar información de validación de nuevo al usuario.

Aumentar las excepciones es costoso en cuanto a recursos y lento. Si tiene varias reglas de validación que debe aplicar, escriba un código específico para estas; probablemente solo debe confiar en el manejo de excepciones para las cosas que no anticipa.

+0

Me preguntaba sobre esto también. Estoy escribiendo una clase de puntaje alto, y el constructor puede tomar un param "max". que indica la puntuación máxima disponible. Bueno, si pasan un número más grande de lo que mi clase admite, estaba lanzando una excepción porque no quería que el constructor terminara con mala información. Soy nuevo en esto, ¿hay una mejor manera de hacerlo? – Ross

+0

Esto es un comentario y no una respuesta al PO. – Drellgor

3

Te recomiendo que revises tu programa con un depurador y verás por ti mismo lo que está sucediendo. ¡Muy útil para aprender!

+0

Este es un gran consejo. ¡Yo haré eso! gracias – Ross

+0

Esto es un "consejo" y no una respuesta a la pregunta original. – Drellgor

+0

Guau, mi bandera de "no respuesta" fue disputada. – Almo

2

Vine aquí en busca de una respuesta a la publicación original y casi me perdí una respuesta muy valiosa publicada por Eric Lippert. Aquí está su respuesta publicada en los comentarios:

Dividir esto en tres preguntas.

(1) ¿Se ejecutará cualquiera de los códigos del método después del lanzamiento?
SÍ. Si la excepción estaba dentro de un intento, entonces se ejecutará el código dentro de los bloques de captura coincidentes o finalmente el bloque. Si no hay un bloque de prueba, entonces NO. El control se ramifica al bloque de excepción más cercano, captura o (en vb) el filtro de excepción bloquea la pila.

(2) ¿Tengo que dejar un descanso después del lanzamiento?
NO, nunca hagas eso. El punto final de la declaración de tiro no es alcanzable; un lanzamiento es tratado como un goto por el compilador. Una afirmación inmediatamente después de un lanzamiento no es alcanzable y nunca se ejecutará.

(3) ¿Un lanzamiento siempre sale del método?
NO. Si el lanzamiento está en un intento y el intento tiene un bloque de catch correspondiente, entonces el bloque catch puede "comerse" la excepción. Solo si no hay un bloque catch, la excepción hace una actualización no local de la pila de llamadas.

Si tiene más preguntas al respecto, le recomiendo leer la especificación C#; todo este comportamiento está claramente documentado.

Por último, parece que estás lanzando excepciones "descabelladas", ya que en "hey, vocero, te dije que nunca me dieras esa información". Eso es genial porque evita errores en los llamantes. Pero si haces eso, ¡debes asegurarte de que la persona que llama tenga alguna forma de saber lo que esperas! Si la persona que llama no puede determinar si va a tirar o no según su documentación, entonces no ha hecho una excepción descarada, ha hecho una molesta excepción. Ver http://blogs.msdn.com/ericlippert/archive/2008/09/10/vexing-exceptions.aspx para más detalles.

+0

Con respecto a su primer punto: C# ahora también tiene filtros de excepción; Ya no es solo para VB. –

Cuestiones relacionadas