← C# EnglishChapter 11 of 13

Exception Handling

## Learning Objectives - Understand exception types - Use try, catch, finally - Throw custom exceptions - Handle exceptions gracefully ## What is an Exception? An event that disrupts normal program flow: ```csharp class Program { static void Main() { int[] numbers = { 1, 2, 3 }; Console.WriteLine(numbers[5]); // IndexOutOfRangeException! } } ``` ## Exception Hierarchy ```text Exception ├── SystemException │ ├── ArgumentException │ ├── IndexOutOfRangeException │ ├── NullReferenceException │ └── InvalidOperationException ├── IOException │ ├── FileNotFoundException │ └── DirectoryNotFoundException ├── FormatException ├── OverflowException └── ... (many more) ``` ## Try-Catch ### Basic Syntax ```csharp try { int result = 10 / 0; // Might throw } catch (ArithmeticException ex) { Console.WriteLine("Cannot divide by zero!"); Console.WriteLine(ex.Message); } ``` ### Multiple Catch ```csharp try { int[] arr = new int[5]; arr[10] = 100; } catch (IndexOutOfRangeException ex) { Console.WriteLine("Array index error!"); } catch (ArithmeticException ex) { Console.WriteLine("Math error!"); } catch (Exception ex) { Console.WriteLine("Generic error: " + ex.Message); } ``` ### Catch Order Most specific first, then general: ```csharp try { // code } catch (NullReferenceException ex) // Specific first { // handle } catch (RuntimeException ex) // Then more general { // handle } catch (Exception ex) // Finally, most general { // handle } ``` ## Finally Block ### Always Executes ```csharp StreamReader? reader = null; try { reader = new StreamReader("file.txt"); string content = reader.ReadToEnd(); Console.WriteLine(content); } catch (FileNotFoundException) { Console.WriteLine("File not found"); } catch (IOException ex) { Console.WriteLine("IO Error: " + ex.Message); } finally { // Always executes, even if exception thrown reader?.Dispose(); } ``` ### Try-with-resources (C# 8+) ```csharp // Compiler generates finally block automatically try { using var reader = new StreamReader("file.txt"); string content = reader.ReadToEnd(); Console.WriteLine(content); } catch (FileNotFoundException) { Console.WriteLine("File not found"); } // reader is automatically disposed ``` ## Throwing Exceptions ### throw Keyword ```csharp public static void ValidateAge(int age) { if (age < 0) { throw new ArgumentException("Age cannot be negative"); } if (age > 150) { throw new ArgumentException("Age is too high"); } } ``` ### Common Exception Types | Type | When to Throw | |------|--------------| | ArgumentException | Invalid argument | | ArgumentNullException | null argument | | InvalidOperationException | Invalid state | | NotSupportedException | Operation not supported | ## Custom Exceptions ### Define Exception Class ```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($"Invalid email: {email}") { } } ``` ### Using Custom Exception ```csharp public static void RegisterUser(string email) { if (!email.Contains("@")) { throw new InvalidEmailException(email); } // registration logic } // Handling try { RegisterUser("invalid"); } catch (InvalidEmailException ex) { Console.WriteLine(ex.Message); // Invalid email: invalid } ``` ## Exception Filters (C# 6+) ### When Clause ```csharp try { // code that might throw } catch (Exception ex) when (ex is ArgumentException or FormatException) { Console.WriteLine("Invalid argument or format"); } catch (Exception ex) when (ex.Message.Contains("specific")) { Console.WriteLine("Specific error occurred"); } ``` ## Common Runtime Exceptions ```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 } ``` ## Exception Properties ```csharp try { RiskyOperation(); } catch (Exception ex) { ex.Message; // Brief description ex.StackTrace; // Call stack ex.InnerException; // Cause exception ex.GetType(); // Exception type } ``` ## Best Practices ### Do ```csharp // Catch specific exceptions try { string content = File.ReadAllText("file.txt"); } catch (FileNotFoundException) { // Handle specific exception } // Clean up with try-with-resources try { using var connection = new DatabaseConnection(); // use connection } // Log and potentially rethrow try { DoSomething(); } catch (Exception ex) { Logger.Error("Failed", ex); throw; // Rethrow original } ``` ### Don't ```csharp // Don't swallow exceptions try { DoSomething(); } catch (Exception) { // Doing nothing hides bugs! } // Don't catch without action try { DoSomething(); } catch (Exception ex) { Console.WriteLine(ex); // At least log it } // Don't catch everything try { DoSomething(); } catch // Empty catch - bad! { } ``` ## Rethrowing Exceptions ### throw vs throw ```csharp catch (Exception ex) { Log(ex); throw ex; // Resets stack trace to this location } catch (Exception ex) { Log(ex); throw; // Preserves original stack trace (preferred) } ``` ## Summary - Exceptions disrupt normal flow - try-catch-finally handles exceptions - finally always executes (or use try-with-resources) - throw throws an exception - Custom exceptions extend Exception - Catch specific exceptions first - Exception filters: `catch when (condition)` - Never silently swallow exceptions - Use `throw;` to rethrow preserved stack trace

Comments

Comments powered by Giscus

To enable comments, add your Giscus embed code here.

Learn more about Giscus →