Deriving Exception Classes


Although C#’s built-in exceptions handle most common errors, C#’s exception handling mechanism is not limited to these errors. In fact, part of the power of C#’s approach to exceptions is its ability to handle exceptions that you create. You can use custom exceptions to handle errors in your own code. Creating an exception type is easy. Just define a class derived from Exception. As a general rule, exceptions defined by you should be derived from ApplicationException since this is the hierarchy reserved for application-related exceptions. Your derived classes don’t need to actually implement anything—it is their existence in the type system that allows you to use them as exceptions.

The exception classes that you create will automatically have the properties and methods defined by Exception available to them. Of course, you can override one or more of these members in exception classes that you create.

Here is an example that makes use of a custom exception type. At the end of Chapter 10 an array class called RangeArray was developed. As you may recall, RangeArray supports single-dimensional int arrays in which the starting and ending index is specified by the user. For example, an array that ranges from 5 to 27 is perfectly legal for a RangeArray. In Chapter 10, if an index was out of range, a special error variable defined by RangeArray was set. This meant that the error variable had to be checked after each operation by the code that used RangeArray. Of course, such an approach is error-prone and clumsy. A far better design is to have RangeArray throw a custom exception when a range error occurs. This is precisely what the following version of RangeArray does:

 // Use a custom Exception for RangeArray errors. using System; // Create a RangeArray exception. class RangeArrayException : ApplicationException {   // Implement the standard constructors   public RangeArrayException() : base() { }   public RangeArrayException(string str) : base(str) { }   // Override ToString for RangeArrayException.   public override string ToString() {     return Message;   } } // An improved version of RangeArray. class RangeArray {   // private data   int[] a; // reference to underlying array   int lowerBound; // lowest index   int upperBound; // greatest index   int len; // underlying var for Length property   // Construct array given its size.   public RangeArray(int low, int high) {     high++;     if(high <= low) {       throw new RangeArrayException("Low index not less than high.");     }     a = new int[high - low];     len = high - low;     lowerBound = low;     upperBound = --high;   }   // Read-only Length property.   public int Length {     get {       return len;     }   }   // This is the indexer for RangeArray.   public int this[int index] {     // This is the get accessor.     get {       if(ok(index)) {         return a[index - lowerBound];       } else {         throw new RangeArrayException("Range Error.");       }     }     // This is the set accessor.     set {       if(ok(index)) {         a[index - lowerBound] = value;       }       else throw new RangeArrayException("Range Error.");     }   }   // Return true if index is within bounds.   private bool ok(int index) {     if(index >= lowerBound & index <= upperBound) return true;     return false;   } } // Demonstrate the index-range array. class RangeArrayDemo {   public static void Main() {     try {       RangeArray ra = new RangeArray(-5, 5);       RangeArray ra2 = new RangeArray(1, 10);       // Demonstrate ra       Console.WriteLine("Length of ra: " + ra.Length);       for(int i = -5; i <= 5; i++)         ra[i] = i;       Console.Write("Contents of ra: ");       for(int i = -5; i <= 5; i++)         Console.Write(ra[i] + " ");       Console.WriteLine("\n");       // Demonstrate ra2       Console.WriteLine("Length of ra2: " + ra2.Length);       for(int i = 1; i <= 10; i++)         ra2[i] = i;       Console.Write("Contents of ra2: ");       for(int i = 1; i <= 10; i++)         Console.Write(ra2[i] + " ");       Console.WriteLine("\n");     } catch (RangeArrayException exc) {        Console.WriteLine(exc);     }     // Now, demonstrate some errors.     Console.WriteLine("Now generate some range errors.");     // Use an invalid constructor.     try {       RangeArray ra3 = new RangeArray(100, -10); // Error     } catch (RangeArrayException exc) {        Console.WriteLine(exc);     }     // Use an invalid index.     try {       RangeArray ra3 = new RangeArray(-2, 2);       for(int i = -2; i <= 2; i++)         ra3[i] = i;       Console.Write("Contents of ra3: ");       for(int i = -2; i <= 10; i++) // generate range error         Console.Write(ra3[i] + " ");     } catch (RangeArrayException exc) {        Console.WriteLine(exc);     }   } }

The output from the program is shown here:

 Length of ra: 11 Contents of ra: -5 -4 -3 -2 -1 0 1 2 3 4 5 Length of ra2: 10 Contents of ra2: 1 2 3 4 5 6 7 8 9 10 Now generate some range errors. Low index not less than high. Contents of ra3: -2 -1 0 1 2 Range Error.

When a range error occurs, RangeArray throws an object of type RangeArrayException. This class is derived from ApplicationException. As explained, an exception class that you create should normally be derived from ApplicationException.

Notice that there are three places in RangeArray that a RangeArrayException is thrown: in the indexer’s get accessor, in the indexer’s set accessor, and by the RangeArray constructor. To catch these exceptions, RangeArray objects must be constructed and accessed from within a try block, as the program illustrates. By using an exception to report errors, RangeArray now acts like one of C#’s built-in types and can be fully integrated into a program’s exception handling mechanism.

Before moving on, you might want to experiment with this program a bit. For example, try commenting-out the override of ToString( ) and observe the results. Also, try creating an exception using the default constructor, and observe what C# generates as its default message.




C# 2.0(c) The Complete Reference
C# 2.0: The Complete Reference (Complete Reference Series)
ISBN: 0072262095
EAN: 2147483647
Year: 2006
Pages: 300

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net