Exception Handling                                    
                                           
C# provides structured exception handling using
try, catch, and finally keywords.  All .NET exceptions derive
from a common type: System.Exception. This class provides a wealth of functionality, including the ability to
retrieve the call stack information.  Furthermore, you can create more powerful custom exception classes by
deriving from Exception and extending its functionality.  The
System.Exception type defines numerous
properties that are common to all exception types.  Be aware that the Data property is only found in .NET 2.0
or higher.


public class Exception : ISerializable, _Exception
{
 public virtual IDictionary Data { get; }

 public virtual string HelpLink { get; set; }
 public Exception InnerException { get; }
 public virtual string Message { get; }
 public virtual string Source { get; set; }
 public virtual string StackTrace { get; }
 public MethodBase TargetSite { get; }
}


Here is an example using try/catch/finally.


public void SomeMethod()
{
 try
 {
   // Code that may raise an exception.
   File.OpenText("SomeFileWhichIsNotHere.txt");
 }
 catch
(FileNotFoundException ex)
 {
   Console.WriteLine("*** Error! ***");
   Console.WriteLine("Stack: {0}", ex.StackTrace);
   throw ex; // <-- rethrows the exception up the stack.
 }
 catch
(Exception ex) // Catches all other exceptions from try scope.
 {
   Console.WriteLine("*** Caught a Exception ***");
   Console.WriteLine("Stack: {0}", ex.StackTrace);
 }
 finally
 {

   // This code will always execute just before
   // exiting the try block.

   Console.WriteLine("*** In the Finally Block ***");
 }
}


Notes on the previous code segment.  You can have multiple catch blocks designed to catch specific types of
exceptions.  The runtime executes the first catch block that matches the exception type. No others are executed.  
The
finally block will always run before execution leaves the try block, even if another exception is thrown from
within a catch.


Building Custom Exceptions

Although the base class libraries have numerous exceptions that can be thrown to account for many runtime
errors, you can easily build your own custom exceptions.
When you wish to build a new custom (strongly
typed) exception, you are able to simply extend System.Exception (or System.ApplicationException).

As detailed in the next chaper, ‘extending’ a class is the act of building new classes based on existing classes.
This technique is also known as ‘inheritance’. When you extend a class from another class, you are able to
‘inherit’ functionality from the existing class.

If you wish to follow Microsoft best practices, all custom exceptions should:
       •        Be marked as serializable using the [Serializable] attribute.
       •        Define a constructor that allows the Message property to be set.
       •        Define a constructor that accounts for any ‘inner exceptions’.
       •        Define a constructor that allows the object to be passed across remoting boundaries.



Here is an example of a custom exception following these best practices.  Don’t concern yourself with the
syntactic details just yet, however do note that the colon operator (:) on the class declaration is used to denote
inheritance.


[Serializable]
public class CarIsDeadException : ApplicationException
{

 // core-ctors.

 public CarIsDeadException() { }
 public CarIsDeadException(string message) : base(message) { }

 // For inner exceptions.

 public CarIsDeadException(string message,
                           System.Exception inner)
                           : base(message, inner) { }

 // For remoting.

 protected CarIsDeadException(
   System.Runtime.Serialization.SerializationInfo info,
   System.Runtime.Serialization.StreamingContext context)
   : base(info, context) { }
}



As of .NET 2.0, the Exception base type now allows you to define and process custom user data via the Data
property.   This property provides access to a dictionary type. Therefore, data can be represented as
name/value pairs.  Assume you have a method in the Car class that will throw a new instance of
CarIsDeadException under the correct circumstances:


// Assume this method is defined in a class named Car.
// This class has a boolean member named carIsDead.

public void Accelerate(int delta)
{

 // Assume we have a boolean member variable to determine the
 // state of the engine.

 if (carIsDead)
 {

   // We need to call the HelpLink property. Thus, we need to
   // create a local variable before throwing the Exception object.

   CarIsDeadException ex =
     new CarIsDeadException("Your car has exploded!");
   ex.HelpLink = "http://www.CarsRUs.com";

   // Stuff in custom data regarding the error.

   ex.Data.Add("TimeStamp",
     string.Format("The car exploded at {0}", DateTime.Now));
   ex.Data.Add("Cause", "You have a lead foot.");
   throw ex;
 }
...
}
}


On the caller’s side, it is important to check that the Data property is not null (meaning no user data has been
supplied).  If Data is not null, we can process the custom data within a catch block as so:


catch(CarIsDeadException e)
{
...

 // By default, the data field is empty, so check for null.

 Console.WriteLine("\n-> Custom Data:");
 if (e.Data != null)
 {
   foreach (DictionaryEntry de in e.Data)
   Console.WriteLine("-> {0}: {1}", de.Key, de.Value);
 }
}
}
C# Exception Handling
Table of Contents
C# Tutorial | C#.NET Tutorial | Exceptions Tutorial

Copyright (c) 2008.  Intertech, Inc. All Rights Reserved.  This information is to be used
strictly prohibited.
Courseware
Training Resources
Tutorials
Services