CSharp/C# Tutorial - C# try catch finally






A try statement specifies a code block subject to error-handling or cleanup code.

The try block must be followed by a catch block, a finally block, or both.

The catch block executes when an error occurs in the try block.

The finally block executes after execution leaves the try block to perform cleanup code, whether or not an error occurred.

A catch block has access to an Exception object that contains information about the error.

You use a catch block to either compensate for the error or rethrow the exception.

You rethrow an exception if you merely want to log the problem, or if you want to rethrow a new, higher-level exception type.

A finally block adds determinism to your program, the CLR will always execute it.

It's useful for cleanup tasks such as closing network connections.

A try statement looks like this:

try {
    ... // exception may get thrown within execution of this block
} catch (ExceptionA ex) {
    ... // handle exception of type ExceptionA
} catch (ExceptionB ex) {
    ... // handle exception of type ExceptionB
} finally {
    ... // cleanup code
}




Example

Consider the following program:

class Main {
    static int Calc (int x) { 
       return 10 / x; 
    }
    static void Main()  {
       int y = Calc (0);
       Console.WriteLine (y);
    }
}

To prevent the runtime throwing a DivideByZeroException in case of x being zero we can catch the exception as follows:

class Main {
    static int Calc (int x) { return 10 / x; }
    static void Main() {
       try {
          int y = Calc (0);
          Console.WriteLine (y);
       } catch (DivideByZeroException ex) {
          Console.WriteLine ("x cannot be zero");
       }
       Console.WriteLine ("program completed");
    }
}




The catch Clause

A catch clause specifies what type of exception to catch.

This must either be System.Exception or a subclass of System.Exception.

Catching System.Exception catches all possible errors.

You can handle multiple exception types with multiple catch clauses:

class Main {
    static void Main (string[] args) {
       try {
           byte b = byte.Parse (args[0]);
           Console.WriteLine (b);
       } catch (IndexOutOfRangeException ex) {
           Console.WriteLine ("Please provide at least one argument");
       } catch (FormatException ex) {
           Console.WriteLine ("That's not a number!");
       } catch (OverflowException ex) {
           Console.WriteLine ("You've given me more than a byte!");
       }
    }
}

An exception can be caught without specifying a variable, if you don't need to access its properties:

catch (StackOverflowException) // no variable
{
    ...
}

We can omit both the variable and the type meaning that all exceptions will be caught:

catch { 
   ... 
}

The finally Block

A finally block always executes.

finally blocks are typically used for cleanup code.

static void methodA() {
    StreamReader reader = null;
    try {
       reader = File.OpenText ("file.txt");
       if (reader.EndOfStream) return;
           Console.WriteLine (reader.ReadToEnd());
    } finally {
       if (reader != null) reader.Dispose();
    }
}