5. Excepciones C#

31
EXCEPCIONES Unidad 5

Transcript of 5. Excepciones C#

Page 1: 5. Excepciones C#

EXCEPCIONES

Unidad 5

Page 2: 5. Excepciones C#

Excepciones

Es posible que, al ejecutar un programa, se presenten errores no esperados que alteren el funcionamiento del mismo o incluso obligando a su finalización. Estos errores no tienen por qué deberse a errores de programación, sino que también pueden aparecer por un uso no esperado del programa por parte del usuario (introducir datos no permitidos, indicar un archivo no existente...).

Podemos evitar los errores prediciendo futuras entradas de datos erróneas o bien podemos tratarlos cuando surjan. Para ello, la Plataforma .NET suministra la clase Exception del espacio de nombres System.

Page 3: 5. Excepciones C#

Excepciones y control de excepciones

Las características de control de excepciones del lenguaje C# proporcionan una manera de afrontar cualquier situación inesperada o excepcional que se presente mientras se ejecuta un programa. El control de excepciones utiliza las palabras clave try, catch y finally para intentar acciones que podrían no realizarse correctamente, controlar errores y limpiar los recursos después.

Page 4: 5. Excepciones C#

Se deben identificar 3 bloques de código cuando se trabaja con excepciones :

El bloque de código que debe usar el procesamiento de excepciones.

Un bloque de código que se ejecuta si se encuentra una excepción mientras se procesa el primer bloque de código.

Un bloque de código opcional que se ejecuta después de que se procese la excepción.

Page 5: 5. Excepciones C#

Información general sobre excepciones

Las excepciones son tipos que se derivan en última instancia de System.Exception. Utilice un bloque try alrededor de las instrucciones que puedan generar excepciones. Cuando se produce una excepción dentro del bloque try, el flujo de control salta al

primer controlador de excepciones asociado que se encuentre en cualquier parte de la pila de llamadas. En C#, la palabra clave catch se utiliza para definir un controlador de excepciones.

Si no hay un controlador de excepciones para una excepción determinada, el programa deja de ejecutarse y presenta un mensaje de error.

No detecte una excepción a menos que pueda controlarla y dejar la aplicación con un estado conocido. Si detecta una excepción System.Exception, vuelva a producirla mediante la palabra clave throw al final del bloque catch.

Si un bloque catch define una variable de excepción, puede utilizar dicho bloque para obtener más información sobre el tipo de excepción que se ha producido.

Un programa que utiliza la palabra clave throw puede generar explícitamente excepciones.

Los objetos de excepción contienen información detallada sobre el error, tal como el estado de la pila de llamadas y una descripción de texto del error.

El código de un bloque finally se ejecuta aunque se produzca una excepción. Use un bloque finally para liberar recursos, por ejemplo, para cerrar las secuencias o archivos que se abrieron en el bloque try.

Page 6: 5. Excepciones C#

Ventajas

Claridad: El uso de códigos especiales para informar de error suele dificultar la legibilidad del fuente en tanto que se mezclan las instrucciones propias de la lógica del mismo con las instrucciones propias del tratamiento de los errores que pudiesen producirse durante su ejecución. Por ejemplo:

 int resultado = obj.Método();if (resultado == 0) // Sin errores al ejecutar obj.Método();{...} else if (resultado == 1) // Tratamiento de error de código 1{...}else if (resultado == 2) // Tratamiento de error de código 2...

Como se verá, utilizando excepciones es posible escribir el código como si nunca se fuesen a producir errores y dejar en una zona aparte todo el código de tratamiento de errores, lo que contribuye a facilitar la legibilidad de los fuentes.

Page 7: 5. Excepciones C#

Ventajas

Más información: A partir del valor de un código de error puede ser difícil deducir las causas del mismo y conseguirlo muchas veces implica tenerse que consultar la documentación que proporcionada sobre el método que lo provocó, que puede incluso que no especifique claramente su causa.

  Por el contrario, una excepción es un objeto que cuenta

con campos que describen las causas del error y a cuyo tipo suele dársele un nombre que resuma claramente su causa. Por ejemplo, para informar errores de división por cero se suele utilizar una excepción predefinida de tipo DivideByZeroException en cuyo campo Message se detallan las causas del error producido.

Page 8: 5. Excepciones C#

Ventajas

Tratamiento asegurado: Cuando se utilizan códigos de error nada obliga a tratarlos en cada llamada al método que los pueda producir, e ignorarlos puede provocar más adelante en el código comportamientos inesperados de causas difíciles de descubrir.

  Cuando se usan excepciones siempre se asegura que

el programador trate toda excepción que pueda producirse o que, si no lo hace, se aborte la ejecución de la aplicación mostrándose un mensaje indicando dónde se ha producido el error.

 

Page 9: 5. Excepciones C#

Excepciones derivadas de System.Exception que se corresponden con los errores más comunes que pueden surgir durante la ejecución de una aplicación.

Tipo de la excepción Causa de que se produzca la excepción

ArgumentException Pasado argumento no válido (base de excepciones de argumentos)

ArgumentNullException Pasado argumento nulo

ArgumentOutOfRangeException

Pasado argumento fuera de rango

ArrayTypeMistmatchException

Asignación a tabla de elemento que no es de su tipo

COMException Excepción de objeto COM

DivideByZeroException División por cero

IndexOutOfRangeException Índice de acceso a elemento de tabla fuera del rango válido (menor que cero o mayor que el tamaño de la tabla)

InvalidCastException Conversión explícita entre tipos no válida

InvalidOperationException Operación inválida en estado actual del objeto

InteropException Base de excepciones producidas en comunicación con código inseguro

NullReferenceException Acceso a miembro de objeto que vale null

OverflowException Desbordamiento dentro de contexto donde se ha de comprobar los desbordamientos (expresión constante, instrucción checked, operación checked u opción del compilador /checked)

OutOfMemoryException Falta de memoria para crear un objeto con new

SEHException Excepción SHE del API Win32

StackOverflowException Desbordamiento de la pila, generalmente debido a un excesivo número de llamadas recurrentes.

TypeInizializationException Ha ocurrido alguna excepción al inicializar los campos estáticos o el constructor estático de un tipo. En InnerException se indica cuál es.

Page 10: 5. Excepciones C#

¿Por qué se emplean excepciones?

El tradicional tratamiento procedural de errores es demasiado complicado

int errorCodigo = 0;FileInfo source = new FileInfo("code.cs");if (errorCodigo == -1) goto Fallo;int longitud = (int)source.Length;if (errorCodigo == -2) goto Fallo;char[] contenido = new char[longitud];if (errorCodigo == -3) goto Fallo;// No hay problemas ...Fallo: ...

int errorCodigo = 0;FileInfo source = new FileInfo("code.cs");if (errorCodigo == -1) goto Fallo;int longitud = (int)source.Length;if (errorCodigo == -2) goto Fallo;char[] contenido = new char[longitud];if (errorCodigo == -3) goto Fallo;// No hay problemas ...Fallo: ... Trat. De erroresTrat. De errores

Lógica del programaLógica del programa

Page 11: 5. Excepciones C#

Ejemplo

class ExceptionTest

{

static double SafeDivision(double x, double y)

{

if (y == 0)

throw new System.DivideByZeroException();

return x / y;

}

static void Main()

{

// Input for test purposes. Change values

// to see exception handling behavior.

double a = 98, b = 0;

double result = 0;

try

{

result = SafeDivision(a, b);

Console.WriteLine("{0} dividido entre {1} = {2}", a, b, result);

}

catch (DivideByZeroException )

{

Console.WriteLine(“Intentas dividir entre cero.");

}

}

}

Page 12: 5. Excepciones C#

Uso de bloques try-catch Solución orientada a objetos para el

tratamiento de errores Poner el código normal en un bloque try Tratar las excepciones en un bloque

catch aparte

try {Console.WriteLine("Escriba un número");int i = int.Parse(Console.ReadLine());

}catch (OverflowException capturada){

Console.WriteLine(capturada);}

try {Console.WriteLine("Escriba un número");int i = int.Parse(Console.ReadLine());

}catch (OverflowException capturada){

Console.WriteLine(capturada);}

Tratamiento de erroresTratamiento de errores

Lógica del programaLógica del programa

Page 13: 5. Excepciones C#

Bloques catch múltiples Cada bloque catch captura una clase de excepcion Un bloque try puede tener un bloque catch general Un bloque try no puede capturar una clase derivada

de una clase capturada en un bloque catch anterior

try {

Console.WriteLine(“Escriba el primer número");int i = int.Parse(Console.ReadLine());Console.WriteLine("Escriba el segundo número");int j = int.Parse(Console.ReadLine());int k = i / j;

}catch (OverflowException capturada) {…}catch (DivideByZeroException capturada) {…}

try {

Console.WriteLine(“Escriba el primer número");int i = int.Parse(Console.ReadLine());Console.WriteLine("Escriba el segundo número");int j = int.Parse(Console.ReadLine());int k = i / j;

}catch (OverflowException capturada) {…}catch (DivideByZeroException capturada) {…}

Page 14: 5. Excepciones C#

El siguiente código ayudará a comprender mejor lo que ocurre en un bloque try-catch múltiple:

try { Console.WriteLine("Escriba el primer número");

int i = int.Parse(Console.ReadLine()); Console.WriteLine("Escriba el segundo número"); int j = int.Parse(Console.ReadLine()); int k = i / j;

} catch (OverflowException capturada) {

Console.WriteLine(capturada); }

catch(DivideByZeroException capturada) { Console.WriteLine(capturada); }

. ...

Page 15: 5. Excepciones C#

La instrucción throw

Lanza una excepción apropiada Asigna a la excepción un mensaje

significativo

throw expression ;throw expression ;

if (minuto < 1 || minuto >= 60) { throw new InvalidTimeException(minuto + " no es un minuto válido"); // !! No alcanzado !!}

if (minuto < 1 || minuto >= 60) { throw new InvalidTimeException(minuto + " no es un minuto válido"); // !! No alcanzado !!}

Page 16: 5. Excepciones C#

La cláusula finally

Las instrucciones de un bloque finally se ejecutan

Monitor.Enter(x);try { ...}finally { Monitor.Exit(x);}

Monitor.Enter(x);try { ...}finally { Monitor.Exit(x);}

Bloques catch opcionalesBloques catch opcionales

Page 17: 5. Excepciones C#

Comprobación de desbordamiento aritmético

Por defecto, el desbordamiento aritmético no se comprueba Un comando checked activa la comprobación de

desbordamiento

checked { int numero = int.MaxValue; Console.WriteLine(++numero);}

checked { int numero = int.MaxValue; Console.WriteLine(++numero);}

unchecked { int numero = int.MaxValue; Console.WriteLine(++numero);}

unchecked { int numero = int.MaxValue; Console.WriteLine(++numero);} -2147483648

OverflowExceptionOverflowException

Se lanza un objeto excepción.WriteLine no se ejecuta

MaxValue + 1 es negativo?

Page 18: 5. Excepciones C#

Normas para el tratamiento de excepciones

Lanzamiento Evitar excepciones para casos normales o

esperados Nunca crear ni lanzar objetos de clase

Exception Incluir una cadena de descripción en un objeto

Exception Lanzar objetos de la clase más específica

posible

Captura Ordenar los bloques catch de lo específico a lo

general No permitir que salgan excepciones de Main

Page 19: 5. Excepciones C#

Excepciones

Una excepción es el indicador de un problema: una mala operación o situación anómala que ocurre durante la ejecución de un programa. Las excepciones deben ser interceptadas y manejadas para no desestabilizar el programa. Todas las excepciones son instancias de System.Exception o de sus derivadas. El CLR provee un número amplio de excepciones predefinidas: ArgumentNullException, InvalidCastException, OverflowException, etc. Se pueden crear excepciones personalizadas derivando de System.Exception.

Page 20: 5. Excepciones C#

Manejando las excepciones

Las excepciones deben ser atrapadas y controladas para asegurar la continuidad del programa.

Si la función en ejecución C() no intercepta la excepción, se le da la oportunidad a la función B() o función solicitante. Si B() no intercepta la excepción, se la da la oportunidad a

la función A(). Si A() no intercepta la excepción, el CLR la intercepta y

termina el programa en forma abrupta.

Las excepciones se manejan con las sentencias: try - catch - finally

Page 21: 5. Excepciones C#

Sentencias try-catch

Encerrar cualquier código sospechoso de generar una excepción dentro de un bloque try.

Atrapar la excepción lanzada dentro del bloque catch.–Consisten en un bloque try seguida de una o más cláusulas catch.–No se pueden utilizar variables que han sido declaradas dentro de un bloque try,

fuera del mismo.

int SafeDivision(int x, int y) {

try{

return (x / y); }catch (System.DivideByZeroException dbz) { System.Console.WriteLine("Division by zero attempted!"); return 0;}

}

Page 22: 5. Excepciones C#

Clausula catch

Page 23: 5. Excepciones C#

Cláusula catch

La cláusula catch puede ser utilizada sin argumentos, la cual captura cualquier tipo de excepción.

public void Func2( ) {

Console.WriteLine( "Enter Func2..." ); try { Console.WriteLine( "Entering try block..." ); throw new ApplicationException( ); // this code never executes because of the exception Console.WriteLine( "Exiting try block..." ); }catch { Console.WriteLine( "Exception caught and handled!" ); }

Console.WriteLine( "Exit Func2..." ); }

Page 24: 5. Excepciones C#

Cláusula catch

Pueden existir múltiples cláusulas catch, las cuales pueden tomar un argumento de tipo objeto, derivado de System.Exception.

static void Main() {

try{

string s = null; ProcessString(s);

} // Most specific: catch (ArgumentNullException e)

{ Console.WriteLine("{0} First exception caught.", e);

}// Least specific: catch (Exception e) {

Console.WriteLine("{0} Second exception caught.", e);}}

Page 25: 5. Excepciones C#

Tipos de catch

Page 26: 5. Excepciones C#

Sentencia throw

Las excepciones se pueden relanzar, para ser recapturadas por el método solicitante, o capa superior.

Se puede utilizar el catch sin parámetros para excepciones no-manejadas por el CLR.

try { // try to access a resource }

catch { throw; // re-throw the error }

try { // try to access a resource }

catch (System.UnauthorizedAccessException e)

{ LogError(e); // call a custom error logging

procedure

throw e; // re-throw the error //throw; // also works !!

}

Page 27: 5. Excepciones C#

Sentencias try-catch-finally

El bloque finally es útil para limpiar y liberar recursos utilizados en el bloque try. Se puede utilizar para cerrar conexiones a BD, cerrar

archivos, limpiar el buffer, etc. Se ejecuta después de la ejecución de los bloques try y catch. El bloque finally siempre se ejecuta, independiente del resultado del bloque try.

public class MainClass { static void Main() {

int i = 123;string s = "Some string";object o = s;try{

// Invalid conversion; „o‟ contains a string not an int i = (int)o;

}finally {

Console.Write("i = {0}", i); } } }

Page 28: 5. Excepciones C#

Try – catch - finally

Page 29: 5. Excepciones C#

Ejemplos Sentencias try-catch-finally

static void CodeWithCleanup() {

System.IO.FileStream file = null; System.IO.FileInfo fileInfo = null;

try {

fileInfo = new System.IO.FileInfo("C:\\file.txt"); file = fileInfo.OpenWrite(); file.WriteByte(0xF);

}catch(System.Exception e) {

System.Console.WriteLine(e.Message); }finally {

if (file != null){

file.Close(); }

} }

using System;public class EHClass{ static void Main()

{ try { Console.WriteLine("Executing the try statement.");

throw new NullReferenceException(); }

catch (NullReferenceException e) { Console.WriteLine("{0} Caught exception #1.",

e); }

catch { Console.WriteLine("Caught exception #2."); }

finally { Console.WriteLine("Executing finally block.“);}

}}

Page 30: 5. Excepciones C#

La Clase System.Exception

PropiedadStackTrace (string / read-only) Devuelve una cadena con el nombre de los

métodos de la pila. Devuelve el número de línea donde se generó la

excepción en cada método. PropiedadMessage (string / read-only)

Devuelve una cadena explicativa de la razón de la excepción.

PropiedadHelpLink (string / read-only) Se puede establecer para devolver un link con

información de ayuda para resolver el problema.

Page 31: 5. Excepciones C#

Ejemplos de uso de la clase Exception

public void Run( ) {

try{Console.WriteLine( "Open file here" );double a = 12;double b = 0;Console.WriteLine( "{0} / {1} = {2}“, a, b, DoDivide( a, b ) );Console.WriteLine("This line may or may not print" );

}// most derived exception type first

catch (DivideByZeroException e ) { Console.WriteLine(“DivideByZeroException! Msg: {0}“,e.Message );Console.WriteLine(“HelpLink: {0}", e.HelpLink );Console.WriteLine(“Here's a stack trace: {0}\n“, e.StackTrace );}catch {Console.WriteLine("Unknown exception caught" );

}finally {Console.WriteLine("Close file here." );}

}