Free mag vol1 | Page 329

CHAPTER 7  UNDERSTANDING STRUCTURED EXCEPTION HANDLING  Note In practice, few .NET developers build custom exceptions that extend ApplicationException. Rather, it is more common to simply subclass System.Exception; however, either approach is technically valid. Building Custom Exceptions, Take One While you can always throw instances of System.Exception to signal a runtime error (as shown in the first example), it is sometimes advantageous to build a strongly typed exception that represents the unique details of your current problem. For example, assume you want to build a custom exception (named CarIsDeadException) to represent the error of speeding up a doomed automobile. The first step is to derive a new class from System.Exception/System.ApplicationException (by convention, all exception classes end with the “Exception” suffix; in fact, this is a .NET best practice).  Note As a rule, all custom exception classes should be defined as public classes (recall, the default access modifier of a non-nested type is internal). The reason is that exceptions are often passed outside of assembly boundaries, and should therefore be accessible to the calling code base. Create a new Console Application project named CustomException, and copy the previous Car.cs and Radio.cs files into your new project using the Project Add Existing Item menu option (for clarity, be sure to change the namespace that defines the Car and Radio types from SimpleException to CustomException). Next, add the following class definition: // This custom exception describes the details of the car-is-dead condition. // (Remember, you can also simply extend Exception.) public class CarIsDeadException : ApplicationException {} As with any class, you are free to include any number of custom members that can be called within the catch block of the calling logic. You are also free to override any virtual members defined by your parent classes. For example, we could implement the CarIsDeadException by overriding the virtual Message property. As well, rather than populating a data dictionary (via the Data property) when throwing our exception, our constructor allows the sender to pass in a time stamp and reason for the error. Finally, the time stamp data and cause of the error can be obtained using strongly typed properties: public class CarIsDeadException : ApplicationException { private string messageDetails = String.Empty; public DateTime ErrorTimeStamp {get; set;} public string CauseOfError {get; set;} public CarIsDeadException(){} public CarIsDeadException(string message, string cause, DateTime time) { 267