BlackWaspTM

This web site uses cookies. By using the site you accept the cookie policy.This message is for compliance with the UK ICO law.

C# Programming
.NET 1.1+

C# Exception Handling

The thirty-fourth part of the C# Fundamentals tutorial begins a review of exception handling. When an unexpected event occurs, unhandled exceptions cause a program to exit abnormally. Correct handling permits the graceful recovery from an error condition.

Catching Specific Exceptions

So far, the examples described have included code to catch all exceptions. Sometimes you will want to catch only a specific type of exception so that different problems can be handled in different ways. In order to catch a more specialised exception, the class of exception is named in the catch statement. The following example uses this method to only catch division by zero. Any other exception remains unhandled.

static void Main(string[] args)
{
    int value = 50;
    int divisor = 0;
    int calculated;

    try
    {
        calculated = value / divisor;
    }
    catch (DivideByZeroException ex)            // Catch specific exception only
    {
        Console.WriteLine("Division by zero occurred.");
        Console.WriteLine(ex.Message);          // Report the error message
        calculated = int.MaxValue;
    }

    Console.WriteLine("Result = {0}", calculated);
}

/* OUTPUT

Division by zero occurred.
Attempted to divide by zero.
Result = 2147483647

*/

Catching specific exception types provides two benefits. Firstly, unexpected exceptions such as out of memory are not caught and misinterpreted or masked causing unexpected side effects. Secondly, any additional properties associated with the specialised exception class are made available in the catch block.

NB: If catching the exception type is enough and it is not necessary to interrogate the exception properties then there is no need to include a variable name for the exception object. The catch in the above example could be shortened to catch (DivideByZeroException) in such a situation.

Catching Multiple Exceptions

When developing complex routines, it is possible that many different types of exception could occur. Each of these exceptions may require handling in a different manner. To permit this, multiple catch blocks may be added to a single try block. Each catch block handles a different exception type with the most specific types processed first and the most generic exceptions last.

Each catch block is checked in turn to see if the exception thrown is the same type as, or derives from, that declared in the statement. When a match is found, the code within the catch block is executed. Only one catch block's code is ever executed. Exceptions thrown that do not match any of the declared types remain unhandled.

The following example includes three catch blocks. The first handles division by zero errors. The second responds to a general arithmetic exception but is not used if division by zero occurs. The final catch does not specify the type of exception to catch so is executed for all other exceptions.

static void Main(string[] args)
{
    int value = 50;
    int divisor = 0;
    int calculated;

    try
    {
        calculated = value / divisor;
    }
    catch (DivideByZeroException)               // Division by zero?
    {
        Console.WriteLine("Division by zero occurred.");
        calculated = int.MaxValue;
    }
    catch (ArithmeticException)                 // Arithmetic exception?
    {
        Console.WriteLine("An arithmetic exception occurred.");
        calculated = int.MaxValue;
    }
    catch
    {
        Console.WriteLine("An unexpected exception occurred.");
        calculated = int.MaxValue;
    }

    Console.WriteLine("Result = {0}", calculated);
}

/* OUTPUT

Division by zero occurred.
Result = 2147483647

*/

The Try / Catch / Finally Block

Sometimes you need to ensure that some code executes whether an exception occurs or not. For example, if a file is opened before a block, this file should be closed following successful processing or an exception.

C# defines an addition block that may be added to the end of the try / catch structure. This is the finally block. The code within this section is guaranteed to execute after the try / catch block, even if any an exception is thrown or the try block includes a return statement.

static void Main(string[] args)
{
    int value = 50;
    int divisor = 0;
    int calculated;

    try
    {
        calculated = value / divisor;
    }
    catch
    {
        Console.WriteLine("An error occurred during division.");
        calculated = int.MaxValue;
    }
    finally
    {
        Console.WriteLine("Clearing up any resources.");
    }

    Console.WriteLine("Result = {0}", calculated);
}

/* OUTPUT

An error occurred during division.
Clearing up any resources.
Result = 2147483647

*/

It is possible to use try and finally together with no catch blocks. If an exception occurs when using such a structure it remains unhandled and is thrown to the calling routine or the C# runtime system. However, the code in the finally block is executed whether an exception is raised or not.

29 March 2007