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 }
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"); } }
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 {
...
}
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(); } }