Catching Derived Class Exceptions


You need to be careful how you order catch statements when trying to catch exception types that involve base and derived classes, because a catch clause for a base class will also match any of its derived classes. For example, since the base class of all exceptions is Exception, catching Exception catches all possible exceptions. Of course, using catch without an argument provides a cleaner way to catch all exceptions, as described earlier. However, the issue of catching derived class exceptions is very important in other contexts, especially when you create exceptions of your own.

If you want to catch exceptions of both a base class type and a derived class type, put the derived class first in the catch sequence. If you don’t, then the base class catch will also catch all derived classes. This rule is self-enforcing because putting the base class first causes unreachable code to be created, since the derived class catch clause can never execute. In C#, an unreachable catch clause is an error.

The following program creates two exception classes called ExceptA and ExceptB. ExceptA is derived from ApplicationException. ExceptB is derived from ExceptA. The program then throws an exception of each type. Pay special attention to the catch statements.

 // Derived exceptions must appear before base class exceptions. using System; // Create an exception. class ExceptA : ApplicationException {   public ExceptA() : base() { }   public ExceptA(string str) : base(str) { }   public override string ToString() {     return Message;   } } // Create an exception derived from ExceptA class ExceptB : ExceptA {   public ExceptB() : base() { }   public ExceptB(string str) : base(str) { }   public override string ToString() {     return Message;   } } class OrderMatters {   public static void Main() {     for(int x = 0; x < 3; x++) {       try {         if(x==0) throw new ExceptA("Caught an ExceptA exception");         else if(x==1) throw new ExceptB("Caught an ExceptB exception");         else throw new Exception();       }       catch (ExceptB exc) {         // catch the exception         Console.WriteLine(exc);       }       catch (ExceptA exc) {         // catch the exception         Console.WriteLine(exc);       }       catch (Exception exc) {         Console.WriteLine(exc);       }     }   } }

The output from the program is shown here:

 Caught an ExceptA exception Caught an ExceptB exception System.Exception: Exception of type 'System.Exception' was thrown.    at OrderMatters.Main()

Notice the type and order of the catch statements. This is the only order in which they can occur. Since ExceptB is derived from ExceptA, the catch statement for ExceptB must be before the one for ExceptA. Similarly, the catch for Exception (which is the base class for all exceptions) must appear last. To prove this point for yourself, try rearranging the catch statements. Doing so will result in a compile-time error.

One good use of a base-class catch clause is to catch an entire category of exceptions. For example, imagine that you are creating a set of exceptions for some device. If you derive all of the exceptions from a common base class, then applications that don’t need to know precisely what problem occurred could simply catch the base class exception, avoiding the unnecessary duplication of code.




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