← C# EspañolChapter 11 of 13

Manejo de Excepciones

## Objetivos de Aprendizaje - Comprender tipos de excepciones - Usar try, catch, finally - Lanzar excepciones personalizadas - Manejar excepciones con gracia ## ¿Qué es una Excepción? Un evento que interrumpe el flujo normal del programa: ```csharp class Program { static void Main() { int[] numbers = { 1, 2, 3 }; Console.WriteLine(numbers[5]); // ¡IndexOutOfRangeException! } } ``` ## Jerarquía de Excepciones ```text Exception ├── SystemException │ ├── ArgumentException │ ├── IndexOutOfRangeException │ ├── NullReferenceException │ └── InvalidOperationException ├── IOException │ ├── FileNotFoundException │ └── DirectoryNotFoundException ├── FormatException ├── OverflowException └── ... (muchas más) ``` ## Try-Catch ### Sintaxis Básica ```csharp try { int result = 10 / 0; // Podría lanzar excepción } catch (ArithmeticException ex) { Console.WriteLine("¡No se puede dividir por cero!"); Console.WriteLine(ex.Message); } ``` ### Múltiples Catch ```csharp try { int[] arr = new int[5]; arr[10] = 100; } catch (IndexOutOfRangeException ex) { Console.WriteLine("¡Error de índice de arreglo!"); } catch (ArithmeticException ex) { Console.WriteLine("¡Error matemático!"); } catch (Exception ex) { Console.WriteLine("Error genérico: " + ex.Message); } ``` ### Orden de Catch Lo más específico primero, luego lo general: ```csharp try { // código } catch (NullReferenceException ex) // Específico primero { // manejar } catch (RuntimeException ex) // Luego lo más general { // manejar } catch (Exception ex) // Finalmente, lo más general { // manejar } ``` ## Bloque Finally ### Siempre Se Ejecuta ```csharp StreamReader? reader = null; try { reader = new StreamReader("file.txt"); string content = reader.ReadToEnd(); Console.WriteLine(content); } catch (FileNotFoundException) { Console.WriteLine("Archivo no encontrado"); } catch (IOException ex) { Console.WriteLine("Error de E/S: " + ex.Message); } finally { // Siempre se ejecuta, incluso si se lanza excepción reader?.Dispose(); } ``` ### Try-with-resources (C# 8+) ```csharp // El compilador genera el bloque finally automáticamente try { using var reader = new StreamReader("file.txt"); string content = reader.ReadToEnd(); Console.WriteLine(content); } catch (FileNotFoundException) { Console.WriteLine("Archivo no encontrado"); } // reader se disposing automáticamente ``` ## Lanzar Excepciones ### Palabra Clave throw ```csharp public static void ValidateAge(int age) { if (age < 0) { throw new ArgumentException("La edad no puede ser negativa"); } if (age > 150) { throw new ArgumentException("La edad es muy alta"); } } ``` ### Tipos Comunes de Excepciones | Tipo | Cuándo Lanzar | |------|---------------| | ArgumentException | Argumento inválido | | ArgumentNullException | Argumento null | | InvalidOperationException | Estado inválido | | NotSupportedException | Operación no soportada | ## Excepciones Personalizadas ### Definir Clase de Excepción ```csharp public class ValidationException : Exception { public ValidationException() { } public ValidationException(string message) : base(message) { } public ValidationException(string message, Exception inner) : base(message, inner) { } } public class InvalidEmailException : ValidationException { public InvalidEmailException(string email) : base($"Email inválido: {email}") { } } ``` ### Usar Excepción Personalizada ```csharp public static void RegisterUser(string email) { if (!email.Contains("@")) { throw new InvalidEmailException(email); } // lógica de registro } // Manejo try { RegisterUser("inválido"); } catch (InvalidEmailException ex) { Console.WriteLine(ex.Message); // Email inválido: inválido } ``` ## Filtros de Excepciones (C# 6+) ### Cláusula when ```csharp try { // código que podría lanzar excepción } catch (Exception ex) when (ex is ArgumentException or FormatException) { Console.WriteLine("Argumento o formato inválido"); } catch (Exception ex) when (ex.Message.Contains("específico")) { Console.WriteLine("Ocurrió un error específico"); } ``` ## Excepciones Comunes de Runtime ```csharp // NullReferenceException string? str = null; str.Length; // NRE // IndexOutOfRangeException int[] arr = { 1, 2 }; arr[5] = 10; // IOR // DivideByZeroException int x = 10 / 0; // DBZ // FormatException int.Parse("abc"); // FP // InvalidCastException object obj = "hello"; int num = (int)obj; // ICE // OverflowException checked { int i = int.MaxValue; i++; // OE } ``` ## Propiedades de Excepciones ```csharp try { RiskyOperation(); } catch (Exception ex) { ex.Message; // Descripción breve ex.StackTrace; // Pila de llamadas ex.InnerException; // Excepción causante ex.GetType(); // Tipo de excepción } ``` ## Mejores Prácticas ### Hacer ```csharp // Capturar excepciones específicas try { string content = File.ReadAllText("file.txt"); } catch (FileNotFoundException) { // Manejar excepción específica } // Limpiar con try-with-resources try { using var connection = new DatabaseConnection(); // usar conexión } // Registrar y posiblemente relanzar try { DoSomething(); } catch (Exception ex) { Logger.Error("Falló", ex); throw; // Relanzar original } ``` ### No Hacer ```csharp // No tragar excepciones try { DoSomething(); } catch (Exception) { // ¡No hacer nada oculta bugs! } // No capturar sin acción try { DoSomething(); } catch (Exception ex) { Console.WriteLine(ex); // Al menos registrarlo } // No capturar todo try { DoSomething(); } catch // Catch vacío - ¡malo! { } ``` ## Relanzar Excepciones ### throw vs throw ```csharp catch (Exception ex) { Log(ex); throw ex; // Reinicia la pila de llamadas a esta ubicación } catch (Exception ex) { Log(ex); throw; // Preserva la pila de llamadas original (preferido) } ``` ## Resumen - Las excepciones interrumpen el flujo normal - try-catch-finally maneja excepciones - finally siempre se ejecuta (o usar try-with-resources) - throw lanza una excepción - Las excepciones personalizadas extienden Exception - Capturar excepciones específicas primero - Filtros de excepciones: `catch when (condición)` - Nunca tragar excepciones silenciosamente - Usar `throw;` para relanzar con pila de llamadas preservada

Comments

Comments powered by Giscus

To enable comments, add your Giscus embed code here.

Learn more about Giscus →