User-Defined Exception Classes

In many cases, you can use existing exception classes from the .NET Framework Class Library to indicate exceptions that occur in your programs. However, in some cases, you might wish to create new exception classes specific to the problems that occur in your programs. User-defined exception classes should derive directly or indirectly from class ApplicationException of namespace System.

Good Programming Practice 12 1

Associating each type of malfunction with an appropriately named exception class improves program clarity.

Software Engineering Observation 12 3

Before creating a user-defined exception class, investigate the existing exceptions in the .NET Framework Class Library to determine whether an appropriate exception type already exists.

Figures 12.6 and 12.7 demonstrate a user-defined exception class. Class NegativeNumberException (Fig. 12.6) is a user-defined exception class representing exceptions that occur when a program performs an illegal operation on a negative number, such as attempting to calculate its square root.

Figure 12.6. ApplicationException derived class thrown when a program performs an illegal operation on a negative number.

(This item is displayed on page 588 in the print version)

1 // Fig. 12.6: NegativeNumberException.cs 2 // NegativeNumberException represents exceptions caused by 3 // illegal operations performed on negative numbers. 4 using System; 5 6 namespace SquareRootTest 7 { 8 class NegativeNumberException : ApplicationException 9 { 10 // default constructor 11 public NegativeNumberException() 12 : base( "Illegal operation for a negative number" ) 13 { 14 // empty body 15 } // end default constructor 16 17 // constructor for customizing error message 18 public NegativeNumberException( string messageValue ) 19 : base( messageValue ) 20 { 21 // empty body 22 } // end one-argument constructor 23 24 // constructor for customizing the exception's error 25 // message and specifying the InnerException object 26 public NegativeNumberException( string messageValue, 27 Exception inner ) 28 : base( messageValue, inner ) 29 { 30 // empty body 31 } // end two-argument constructor 32 } // end class NegativeNumberException 33 } // end namespace SquareRootTest

Figure 12.7. SquareRootForm class throws an exception if an error occurs when calculating the square root.

(This item is displayed on pages 589 - 590 in the print version)

1 // Fig. 12.7: SquareRootTest.cs 2 // Demonstrating a user-defined exception class. 3 using System; 4 using System.Windows.Forms; 5 6 namespace SquareRootTest 7 { 8 public partial class SquareRootForm : Form 9 { 10 public SquareRootForm() 11 { 12 InitializeComponent(); 13 } // end constructor 14 15 // computes square root of parameter; throws 16 // NegativeNumberException if parameter is negative 17 public double SquareRoot( double value ) 18 { 19 // if negative operand, throw NegativeNumberException 20 if ( value < 0 ) 21 throw new NegativeNumberException( 22 "Square root of negative number not permitted" ); 23 else 24 return Math.Sqrt( value ); // compute square root 25 } // end method SquareRoot 26 27 // obtain user input, convert to double, calculate square root 28 private void SquareRootButton_Click( object sender, EventArgs e ) 29 { 30 OutputLabel.Text = ""; // clear OutputLabel 31 32 // catch any NegativeNumberException thrown 33 try 34 { 35 double result = 36 SquareRoot( Convert.ToDouble( InputTextBox.Text ) ); 37 38 OutputLabel.Text = result.ToString(); 39 } // end try 40 catch ( FormatException formatExceptionParameter ) 41 { 42 MessageBox.Show( formatExceptionParameter.Message, 43 "Invalid Number Format", MessageBoxButtons.OK, 44 MessageBoxIcon.Error ); 45 } // end catch 46 catch ( NegativeNumberException 47 negativeNumberExceptionParameter ) 48 { 49 MessageBox.Show( negativeNumberExceptionParameter.Message, 50 "Invalid Operation", MessageBoxButtons.OK, 51 MessageBoxIcon.Error ); 52 } // end catch 53 } // end method SquareRootButton_Click 54 } // end class SquareRootForm 55 } // end namespace SquareRootTest

(a)

(b)

(c)

(d)

According to "Best Practices for Handling Exceptions [C#]," user-defined exceptions should extend class ApplicationException, have a class name that ends with "Exception" and define three constructors: a parameterless constructor; a constructor that receives a string argument (the error message); and a constructor that receives a string argument and an Exception argument (the error message and the inner exception object). Defining these three constructors makes your exception class more flexible, allowing other programmers to easily use and extend it.

NegativeNumberExceptions most frequently occur during arithmetic operations, so it seems logical to derive class NegativeNumberException from class ArithmeticException. However, class ArithmeticException derives from class SystemExceptionthe category of exceptions thrown by the CLR. Recall that user-defined exception classes should inherit from ApplicationException rather than SystemException.

Class SquareRootForm (Fig. 12.7) demonstrates our user-defined exception class. The application enables the user to input a numeric value, then invokes method SquareRoot (lines 1725) to calculate the square root of that value. To perform this calculation, SquareRoot invokes class Math's Sqrt method, which receives a double value as its argument. Normally, if the argument is negative, method Sqrt returns NaN. In this program, we would like to prevent the user from calculating the square root of a negative number. If the numeric value that the user enters is negative, method SquareRoot throws a NegativeNumberException (lines 2122). Otherwise, SquareRoot invokes class Math's method Sqrt to compute the square root (line 24).

When the user inputs a value and clicks the Square Root button, the program invokes event handler SquareRootButton_Click (lines 2853). The TRy statement (lines 3352) attempts to invoke SquareRoot using the value input by the user. If the user input is not a valid number, a FormatException occurs, and the catch block in lines 4045 processes the exception. If the user inputs a negative number, method SquareRoot throws a NegativeNumberException (lines 2122); the catch block in lines 4652 catches and handles this type of exception.

Категории