C# - Exception Handling in C#

Exception Handling in C# - Complete Guide with Examples

Exception Handling in C#

Exception handling in C# is a critical concept for writing robust and error-resilient applications. C# provides a structured and elegant way to handle errors using try, catch, finally, and throw keywords. In this comprehensive guide, we will cover how exception handling works, common exceptions, how to create custom exceptions, best practices, and more.

What is Exception Handling in C#?

Exception handling is the process of responding to the occurrence of exceptionsβ€”anomalous or exceptional conditions that disrupt the normal flow of a program's instructions. C# uses an object-oriented approach to exception handling, allowing developers to manage both system-generated and custom exceptions.

Basic Structure of Exception Handling

try-catch Block

The most common form of exception handling is the try-catch block. The try block contains the code that may throw exceptions, and the catch block handles them.

try
{
    int result = 10 / 0; // Will throw DivideByZeroException
}
catch (DivideByZeroException ex)
{
    Console.WriteLine("Cannot divide by zero.");
}

try-catch-finally Block

The finally block is used to execute code regardless of whether an exception was thrown or not. It's often used to release resources such as file handles or database connections.

try
{
    int[] numbers = {1, 2, 3};
    Console.WriteLine(numbers[5]); // Index out of range
}
catch (IndexOutOfRangeException ex)
{
    Console.WriteLine("Index is out of range.");
}
finally
{
    Console.WriteLine("This block is always executed.");
}

Types of Exceptions in C#

  • System.Exception
  • System.SystemException
  • System.NullReferenceException
  • System.DivideByZeroException
  • System.IndexOutOfRangeException
  • System.InvalidOperationException
  • System.IO.IOException

All exceptions in C# are derived from the base class System.Exception.

The throw Keyword

The throw keyword is used to manually throw an exception.

throw new InvalidOperationException("Operation not allowed.");

Re-throwing Exceptions

You can also re-throw an exception caught in a catch block using a bare throw.

try
{
    // some code
}
catch (Exception ex)
{
    Console.WriteLine("Logging the exception.");
    throw; // rethrows the same exception
}

Multiple Catch Blocks

You can handle different types of exceptions using multiple catch blocks.

try
{
    int[] arr = new int[3];
    Console.WriteLine(arr[5]);
}
catch (IndexOutOfRangeException ex)
{
    Console.WriteLine("Index error: " + ex.Message);
}
catch (Exception ex)
{
    Console.WriteLine("General error: " + ex.Message);
}

Exception Filters

Exception filters allow you to handle exceptions conditionally using the when keyword.

try
{
    int x = 10 / 0;
}
catch (DivideByZeroException ex) when (DateTime.Now.DayOfWeek == DayOfWeek.Monday)
{
    Console.WriteLine("Divide by zero on Monday.");
}

Custom Exceptions

You can create your own exception classes by inheriting from Exception.

public class InvalidAgeException : Exception
{
    public InvalidAgeException(string message) : base(message)
    {
    }
}
try
{
    int age = 15;
    if (age < 18)
        throw new InvalidAgeException("Age must be 18 or above.");
}
catch (InvalidAgeException ex)
{
    Console.WriteLine("Custom Exception: " + ex.Message);
}

Inner Exceptions in C#

An inner exception is used to capture an original exception when a new exception is thrown.

try
{
    try
    {
        int.Parse("abc");
    }
    catch (FormatException ex)
    {
        throw new ApplicationException("Parsing failed", ex);
    }
}
catch (ApplicationException ex)
{
    Console.WriteLine("Outer Exception: " + ex.Message);
    Console.WriteLine("Inner Exception: " + ex.InnerException.Message);
}

Nested try-catch Blocks

Nested try blocks can be used when you want to handle specific exceptions at different levels of logic.

try
{
    try
    {
        string str = null;
        Console.WriteLine(str.Length);
    }
    catch (NullReferenceException ex)
    {
        Console.WriteLine("Null reference handled.");
    }
}
catch (Exception ex)
{
    Console.WriteLine("Outer block handled an exception.");
}

Common Exception Handling Scenarios

Handling File I/O Exceptions

try
{
    string content = File.ReadAllText("file.txt");
    Console.WriteLine(content);
}
catch (FileNotFoundException ex)
{
    Console.WriteLine("File not found.");
}
catch (IOException ex)
{
    Console.WriteLine("An I/O error occurred.");
}

Handling NullReferenceException

string input = null;
try
{
    Console.WriteLine(input.Length);
}
catch (NullReferenceException)
{
    Console.WriteLine("Input is null.");
}

Using Exception Handling in Real-World Applications

Validating User Input

try
{
    Console.WriteLine("Enter age:");
    int age = int.Parse(Console.ReadLine());

    if (age < 0)
        throw new ArgumentOutOfRangeException("Age cannot be negative.");
}
catch (FormatException)
{
    Console.WriteLine("Please enter a valid number.");
}
catch (ArgumentOutOfRangeException ex)
{
    Console.WriteLine(ex.Message);
}

Exception Handling in Asynchronous Methods

public async Task LoadDataAsync()
{
    try
    {
        string data = await File.ReadAllTextAsync("file.txt");
        Console.WriteLine(data);
    }
    catch (Exception ex)
    {
        Console.WriteLine("Error: " + ex.Message);
    }
}

Exception Propagation

Exceptions can propagate up the call stack if not handled immediately.

void Level1()
{
    Level2();
}

void Level2()
{
    Level3();
}

void Level3()
{
    throw new Exception("Something went wrong.");
}

try
{
    Level1();
}
catch (Exception ex)
{
    Console.WriteLine("Caught at top level: " + ex.Message);
}

Exception handling in C# is a powerful mechanism to detect and manage runtime errors. Using try-catch-finally constructs properly can make your application more stable, readable, and professional. Remember to always handle only those exceptions you can deal with, log them appropriately, and avoid overusing general exceptions. Well-structured exception handling contributes to better software quality and maintainability.

By mastering exception handling in C#, you’ll be prepared to build applications that can gracefully recover from unexpected situations and provide a better user experience.

Beginner 5 Hours
Exception Handling in C# - Complete Guide with Examples

Exception Handling in C#

Exception handling in C# is a critical concept for writing robust and error-resilient applications. C# provides a structured and elegant way to handle errors using try, catch, finally, and throw keywords. In this comprehensive guide, we will cover how exception handling works, common exceptions, how to create custom exceptions, best practices, and more.

What is Exception Handling in C#?

Exception handling is the process of responding to the occurrence of exceptions—anomalous or exceptional conditions that disrupt the normal flow of a program's instructions. C# uses an object-oriented approach to exception handling, allowing developers to manage both system-generated and custom exceptions.

Basic Structure of Exception Handling

try-catch Block

The most common form of exception handling is the try-catch block. The try block contains the code that may throw exceptions, and the catch block handles them.

try { int result = 10 / 0; // Will throw DivideByZeroException } catch (DivideByZeroException ex) { Console.WriteLine("Cannot divide by zero."); }

try-catch-finally Block

The finally block is used to execute code regardless of whether an exception was thrown or not. It's often used to release resources such as file handles or database connections.

try { int[] numbers = {1, 2, 3}; Console.WriteLine(numbers[5]); // Index out of range } catch (IndexOutOfRangeException ex) { Console.WriteLine("Index is out of range."); } finally { Console.WriteLine("This block is always executed."); }

Types of Exceptions in C#

  • System.Exception
  • System.SystemException
  • System.NullReferenceException
  • System.DivideByZeroException
  • System.IndexOutOfRangeException
  • System.InvalidOperationException
  • System.IO.IOException

All exceptions in C# are derived from the base class System.Exception.

The throw Keyword

The throw keyword is used to manually throw an exception.

throw new InvalidOperationException("Operation not allowed.");

Re-throwing Exceptions

You can also re-throw an exception caught in a catch block using a bare throw.

try { // some code } catch (Exception ex) { Console.WriteLine("Logging the exception."); throw; // rethrows the same exception }

Multiple Catch Blocks

You can handle different types of exceptions using multiple catch blocks.

try { int[] arr = new int[3]; Console.WriteLine(arr[5]); } catch (IndexOutOfRangeException ex) { Console.WriteLine("Index error: " + ex.Message); } catch (Exception ex) { Console.WriteLine("General error: " + ex.Message); }

Exception Filters

Exception filters allow you to handle exceptions conditionally using the when keyword.

try { int x = 10 / 0; } catch (DivideByZeroException ex) when (DateTime.Now.DayOfWeek == DayOfWeek.Monday) { Console.WriteLine("Divide by zero on Monday."); }

Custom Exceptions

You can create your own exception classes by inheriting from Exception.

public class InvalidAgeException : Exception { public InvalidAgeException(string message) : base(message) { } }
try { int age = 15; if (age < 18) throw new InvalidAgeException("Age must be 18 or above."); } catch (InvalidAgeException ex) { Console.WriteLine("Custom Exception: " + ex.Message); }

Inner Exceptions in C#

An inner exception is used to capture an original exception when a new exception is thrown.

try { try { int.Parse("abc"); } catch (FormatException ex) { throw new ApplicationException("Parsing failed", ex); } } catch (ApplicationException ex) { Console.WriteLine("Outer Exception: " + ex.Message); Console.WriteLine("Inner Exception: " + ex.InnerException.Message); }

Nested try-catch Blocks

Nested try blocks can be used when you want to handle specific exceptions at different levels of logic.

try { try { string str = null; Console.WriteLine(str.Length); } catch (NullReferenceException ex) { Console.WriteLine("Null reference handled."); } } catch (Exception ex) { Console.WriteLine("Outer block handled an exception."); }

Common Exception Handling Scenarios

Handling File I/O Exceptions

try { string content = File.ReadAllText("file.txt"); Console.WriteLine(content); } catch (FileNotFoundException ex) { Console.WriteLine("File not found."); } catch (IOException ex) { Console.WriteLine("An I/O error occurred."); }

Handling NullReferenceException

string input = null; try { Console.WriteLine(input.Length); } catch (NullReferenceException) { Console.WriteLine("Input is null."); }

Using Exception Handling in Real-World Applications

Validating User Input

try { Console.WriteLine("Enter age:"); int age = int.Parse(Console.ReadLine()); if (age < 0) throw new ArgumentOutOfRangeException("Age cannot be negative."); } catch (FormatException) { Console.WriteLine("Please enter a valid number."); } catch (ArgumentOutOfRangeException ex) { Console.WriteLine(ex.Message); }

Exception Handling in Asynchronous Methods

public async Task LoadDataAsync() { try { string data = await File.ReadAllTextAsync("file.txt"); Console.WriteLine(data); } catch (Exception ex) { Console.WriteLine("Error: " + ex.Message); } }

Exception Propagation

Exceptions can propagate up the call stack if not handled immediately.

void Level1() { Level2(); } void Level2() { Level3(); } void Level3() { throw new Exception("Something went wrong."); } try { Level1(); } catch (Exception ex) { Console.WriteLine("Caught at top level: " + ex.Message); }

Exception handling in C# is a powerful mechanism to detect and manage runtime errors. Using try-catch-finally constructs properly can make your application more stable, readable, and professional. Remember to always handle only those exceptions you can deal with, log them appropriately, and avoid overusing general exceptions. Well-structured exception handling contributes to better software quality and maintainability.

By mastering exception handling in C#, you’ll be prepared to build applications that can gracefully recover from unexpected situations and provide a better user experience.

Related Tutorials

Frequently Asked Questions for General

line

Copyrights © 2024 letsupdateskills All rights reserved