6. Exception Handling

Exception Handling in C#

Exception handling allows you to gracefully manage errors or unexpected conditions that occur while a program is running. In C#, all exceptions derive from the base class System.Exception. Two key branches under Exception are SystemException and ApplicationException.

SystemException vs ApplicationException

try, catch, and finally

Example:

try
{
    // Code that may throw exceptions
}
catch (Exception ex)
{
    // Handle exception
}
finally
{
    // Cleanup code (always executes unless a crash)
}

Inner Exceptions

You can nest exception handling in multiple try blocks. If an exception is not handled in an inner try, you can rethrow it or wrap it in another exception to provide more context.

try
{
    try
    {
        Display(null); // May cause NullReferenceException
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
        var result = File.ReadAllText("elvin.txt"); // May cause IOException
    }
}
catch (Exception ex)
{
    Console.WriteLine(ex.Message);
}

Conditional Catch with when

You can use when clauses to refine how exceptions are caught, enabling you to throw more specific exceptions or handle edge cases differently.

static int GetInt(int[] array, int index)
{
    try
    {
        return array[index];
    }
    catch (IndexOutOfRangeException ex) when (index < 0)
    {
        throw new ArgumentOutOfRangeException("Parameter of index cannot be negative", ex);
    }
    catch (IndexOutOfRangeException ex) when (index >= array.Length)
    {
        throw new ArgumentOutOfRangeException("Parameter of index cannot be more than array size", ex);
    }
}

In this example, a single exception type (IndexOutOfRangeException) is handled differently depending on the value of index.

Reference

The content in this document is based on the original notes provided in Azerbaijani. For further details, you can refer to the original document using the following link:

Original Note - Azerbaijani Version