日期:2013-01-14  浏览次数:20441 次

Exception Handling in C#

Level Author
Intermediate Anonymous

What 抯 Wrong with Return Codes?
Most programmers have probably written code that looked like this:
bool success =CallFunction();
if (!success)
{
//process the error
}
This works okay, but every return value has to be checked for an error. If the above
was written as
CallFunction();
any error return would be thrown away. That抯 where bugs come from.
There are many different models for communicating status; some functions
may return an HRESULT , some may return a Boolean value, and others may use
some other mechanism.
In the .NET Runtime world, exceptions are the fundamental method of han-dling
error conditions. Exceptions are nicer than return codes because they can抰
be silently ignored.

Trying and Catching
To deal with exceptions, code needs to be organized a bit differently. The sections
of code that might throw exceptions are placed in a try block, and the code to handle
exceptions in the try block is placed in a catch block. Here抯 an example:


using System;
class Test
{
static int Zero =0;
public static void Main()
{
//watch for exceptions here
try
{
int j =22 /Zero;
}
//exceptions that occur in try are transferred here
catch (Exception e)
{
Console.WriteLine("Exception "+e.Message);
}
Console.WriteLine("After catch");
}
}


The try block encloses an expression that will generate an exception. In this case,
it will generate an exception known as DivideByZeroExceptio . When the division
takes place, the .NET Runtime stops executing code and searches for a try block
surrounding the code in which the exception took place. When it finds a try block,
it then looks for associated catch blocks.
If it finds catch blocks, it picks the best one (more on how it determines which
one is best in a minute), and executes the code within the catch block. The code in
the catch block may process the event or rethrow it.
The example code catches the exception and writes out the message that is
contained within the exception object.
The Exception Hierarchy
All C# exceptions derive from the class named Exception , which is part of the Common
Language Runtime 1 . When an exception occurs, the proper catch block is
determined by matching the type of the exception to the name of the exception
mentioned. A catch block with an exact match wins out over a more general
exception. Returning to the example:
using System;
class Test
{
static int Zero =0;
public static void Main()
{
try
{
int j =22 /Zero;
}
//catch a specific exception
catch (DivideByZeroException e)
{
Console.WriteLine("DivideByZero {0}",e);
}
//catch any remaining exceptions
catch (Exception e)
{
Console.WriteLine("Exception {0}",e);
}
}
}
The catch block that catches the DivideByZeroException is the more specific match,
and is therefore the one that is executed.
This example is a bit more complex:

using System;
class Test
{
static int Zero =0;
static void AFunction()
{
int j = 22 / Zero;
//the following line is never executed.
Console.WriteLine("In AFunction()");
}
public static void Main()
{
try
{
AFunction();
}
catch (DivideByZeroException e)
{
Console.WriteLine("DivideByZero {0}",e);
}
}
}
What happens here?
When the division is executed, an exception is generated. The runtime starts
searching for a try block in AFunction(), but it doesn抰 find one, so it jumps out of
AFunction(), and checks for a try in Main(). It finds one, and then looks for a catch
that matches. The catch b