1
13
Exception
Handling
 2009 Pearson Education, Inc. All rights reserved.
2
And live the purer with the other half.
– William Shakespeare
If they’re running and they don’t look where
they’re going I have to come out from somewhere
and catch them.
– J. D. Salinger
 2009 Pearson Education, Inc. All rights reserved.
3
And oftentimes excusing of a fault
Doth make the fault the worse by the excuse.
– William Shakespeare
O infinite virtue! com’st thou smiling from the
world’s great snare uncaught?
– William Shakespeare
 2009 Pearson Education, Inc. All rights reserved.
4
OBJECTIVES
In this chapter you will learn:
 What exceptions are and how they are handled.
 When to use exception handling.
 To use try blocks to delimit code in which
exceptions might occur.
 To throw exceptions to indicate a problem.
 To use catch blocks to specify exception handlers.
 To use the finally block to release resources.
 The .NET exception class hierarchy.
 Exception properties.
 To create user-defined exceptions.
 2009 Pearson Education, Inc. All rights reserved.
5
13.1 Introduction
13.2 Exception Handling Overview
13.3 Example: Divide by Zero without Exception
Handling
13.4 Example: Handling DivideByZeroExceptions
and FormatExceptions
13.5 .NET Exception Hierarchy
13.6 finally Block
13.7 Exception Properties
13.8 User-Defined Exception Classes
 2009 Pearson Education, Inc. All rights reserved.
6
13.1 Introduction
• An exception is an indication of a problem that occurs
during a program’s execution.
• Exception handling enables applications to resolve
exceptions.
• Exception handling enables clear, robust and more
fault-tolerant programs.
Error-Prevention Tip 13.1
Exception handling helps improve a program’s
fault tolerance.
 2009 Pearson Education, Inc. All rights reserved.
7
13.2 Exception Handling Overview
• Consider the following pseudocode:
Perform a task
If the preceding task did not execute correctly
Perform error processing
Perform next task
If the preceding task did not execute correctly
Perform error processing
…
• In this pseudocode, we begin by performing a task;
then we test whether that task executed correctly.
If not, we perform error processing.
 2009 Pearson Education, Inc. All rights reserved.
8
13.2 Exception Handling Overview (Cont.)
• Exception handling enables programmers to remove
error-handling code from the “main line” of the
program’s execution.
• Programmers can decide to handle all exceptions, all
exceptions of a certain type or all exceptions of related
types.
• Such flexibility reduces the likelihood that errors will
be overlooked.
 2009 Pearson Education, Inc. All rights reserved.
9
Outline
• Figure 13.1’s application divides one input integer by a
second to obtain an int result.
• In this example, we’ll see that an exception is thrown
when a method detects a problem.
DivideByZeroNo
ExceptionHandling
.cs
( 1 of 3 )
1
// Fig. 13.1: DivideByZeroNoExceptionHandling.cs
2
// Integer division without exception handling.
3
using System;
4
5
class DivideByZeroNoExceptionHandling
6
7
8
{
static void Main()
{
9
10
// get numerator and denominator
Console.Write( "Please enter an integer numerator: " );
11
12
int numerator = Convert.ToInt32( Console.ReadLine() );
Console.Write( "Please enter an integer denominator: " );
13
14
15
int denominator = Convert.ToInt32( Console.ReadLine() );
// divide the two integers, then display the result
Converting values can cause
a FormatException.
Converting values can cause
a FormatException.
Fig. 13.1 | Integer division without exception handling. (Part 1 of 3.)
 2009 Pearson Education,
Inc. All rights reserved.
10
Outline
16
int result = numerator / denominator;
17
Console.WriteLine( "\nResult: {0:D} / {1:D} = {2:D}",
18
numerator, denominator, result );
19
} // end Main
20 } // end class DivideByZeroNoExceptionHandling
Please enter an integer numerator: 100
Please enter an integer denominator: 7
Result: 100 / 7 = 14
DivideByZeroNo
ExceptionHandling
.cs
( 2 of 3 )
Division can cause a
DivideByZeroException.
Please enter an integer numerator: 100
Please enter an integer denominator: 0
Unhandled Exception: System.DivideByZeroException:
Attempted to divide by zero.
at DivideByZeroNoExceptionHandling.Main()
in C:\examples\ch13\Fig13_01\DivideByZeroNoExceptionHandling\
DivideByZeroNoExceptionHandling\
DivideByZeroNoExceptionHandling.cs: line 16
Fig. 13.1 | Integer division without exception handling. (Part 2 of 3.)
 2009 Pearson Education,
Inc. All rights reserved.
11
Outline
Please enter an integer numerator: 100
Please enter an integer denominator: hello
DivideByZeroNo
ExceptionHandling
.cs
( 3 of 3 )
Unhandled Exception: System.FormatException:
Input string was not in a correct format.
at System.Number.StringToNumber(String str, NumberStyles options,
NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal)
at System.Number.ParseInt32(String s, NumberStyles style,
NumberFormatInfo info)
at System.Convert.ToInt32(String value)
at DivideByZeroNoExceptionHandling.Main()
in C:\examples\ch13\Fig13_01\DivideByZeroNoExceptionHandling\
DivideByZeroNoExceptionHandling\
DivideByZeroNoExceptionHandling.cs: line 13
Fig. 13.1 | Integer division without exception handling. (Part 3 of 3.)
 2009 Pearson Education,
Inc. All rights reserved.
12
13.3 Example: Divide by Zero without
Exception Handling
• If you run using Debug > Start Debugging,
the program pauses at the line where an exception
occurs.
• Try executing the application from a Command
Prompt window.
• When an error arises, a dialog indicates that the
application has encountered a problem and needs to
close.
• An error message describing the problem is displayed
in the Command Prompt.
 2009 Pearson Education, Inc. All rights reserved.
13
13.3 Example: Divide by Zero without
Exception Handling (Cont.)
• Additional information—known as a stack trace—
displays the exception name and the path of execution
that led to the exception.
• Each “at” line in the stack trace indicates a line of
code in the particular method that was executing when
the exception occurred.
• This information tells where the exception originated,
and what method calls were made to get to that point.
 2009 Pearson Education, Inc. All rights reserved.
14
13.3 Example: Divide by Zero without
Exception Handling (Cont.)
• A FormatException occurs when Convert
method ToInt32 receives a string that does not
represent a valid integer.
• A program may continue executing even though an
exception has occurred and a stack trace has been
printed.
• In such cases, the application may produce incorrect
results.
 2009 Pearson Education, Inc. All rights reserved.
15
Outline
• This application (Fig. 13.2) uses exception handling to
process DivideByZeroExceptions and
FormatExceptions.
• This program demonstrates how to catch and handle
(i.e., deal with) such exceptions.
1
// Fig. 13.2: DivideByZeroTest.cs
2
3
4
// FormatException and DivideByZeroException handlers.
using System;
using System.Windows.Forms;
5
6
7
8
namespace DivideByZeroTest
{
public partial class DivideByZeroTestForm : Form
9
10
11
12
13
14
DivideByZeroTest
.cs
( 1 of 4 )
{
public DivideByZeroTestForm()
{
InitializeComponent();
} // end constructor
Fig. 13.2 | FormatException and DivideByZeroException handlers. (Part 1 of 4.)
 2009 Pearson Education,
Inc. All rights reserved.
16
Outline
15
// obtain 2 integers from the user
16
// and divide numerator by denominator
17
private void divideButton_Click( object sender, EventArgs e )
18
19
{
outputLabel.Text = ""; // clear Label OutputLabel
DivideByZeroTest
.cs
( 2 of 4 )
20
21
22
23
24
// retrieve user input and calculate quotient
try
{
// Convert.ToInt32 generates FormatException
25
26
27
28
// if argument cannot be converted to an integer
int numerator = Convert.ToInt32( numeratorTextBox.Text );
int denominator = Convert.ToInt32( denominatorTextBox.Text );
29
30
// division generates DivideByZeroException
// if denominator is 0
31
32
int result = numerator / denominator;
33
34
35
// display result in OutputLabel
outputLabel.Text = result.ToString();
} // end try
Fig. 13.2 | FormatException and DivideByZeroException handlers. (Part 2 of 4.)
 2009 Pearson Education,
Inc. All rights reserved.
17
Outline
36
catch ( FormatException )
37
38
39
{
40
41
42
43
44
45
MessageBoxIcon.Error );
} // end catch
catch ( DivideByZeroException divideByZeroExceptionParameter )
{
MessageBox.Show( divideByZeroExceptionParameter.Message,
"Attempted to Divide by Zero", MessageBoxButtons.OK,
46
47
48
MessageBox.Show( "You must enter two integers.",
"Invalid Number Format", MessageBoxButtons.OK,
DivideByZeroTest
.cs
( 3 of 4 )
This block catches and handles
a FormatException.
This block catches and
handles a DivideByZeroException.
MessageBoxIcon.Error );
} // end catch
} // end method divideButton_Click
49
} // end class DivideByZeroTestForm
50 } // end namespace DivideByZeroTest
Fig. 13.2 | FormatException and DivideByZeroException handlers. (Part 3 of 4.)
 2009 Pearson Education,
Inc. All rights reserved.
18
a) Performing integer division
Outline
DivideByZeroTest
.cs
( 4 of 4 )
b) Dividing by zero
d) Entering a string value
c) Error message
e) Error message
Fig. 13.2 | FormatException and DivideByZeroException
handlers. (Part 3 of 4.)
 2009 Pearson Education,
Inc. All rights reserved.
19
13.4 Example: Handling
DivideByZeroExceptions and
FormatExceptions
• The Int32.TryParse method converts a string
to an int value if possible.
• The method requires two arguments—one is the
string to parse and the other is the variable in
which the converted value is to be stored.
• The method returns true if the string was parsed
successfully.
• If the string could not be converted, the value 0 is
assigned to the second argument.
 2009 Pearson Education, Inc. All rights reserved.
20
13.4 Example: Handling
DivideByZeroExceptions and
FormatExceptions (Cont.)
13.4.1 Enclosing Code in a try Block
• A try block encloses code that might throw
exceptions and code that is skipped when an exception
occurs.
 2009 Pearson Education, Inc. All rights reserved.
21
13.4 Example: Handling
DivideByZeroExceptions and
FormatExceptions (Cont.)
13.4.2 Catching Exceptions
• When an exception occurs in a try block, a corresponding
catch block catches the exception and handles it.
• At least one catch block must immediately follow a try
block.
• A catch block specifies an exception parameter
representing the exception that the catch block can handle.
• Optionally, you can include a catch block that does not
specify an exception type to catch all exception types.
 2009 Pearson Education, Inc. All rights reserved.
22
13.4 Example: Handling
DivideByZeroExceptions and
FormatExceptions (Cont.)
13.4.3 Uncaught Exceptions
• An uncaught exception (or unhandled exception) is
an exception for which there is no matching catch
block.
• If you run the application from Visual Studio with
debugging, a window called the Exception Assistant
(Fig. 13.3) appears.
 2009 Pearson Education, Inc. All rights reserved.
23
13.4 Example: Handling
DivideByZeroExceptions and
FormatExceptions (Cont.)
Throw point
Exception Assistant
Fig. 13.3 | Exception Assistant.
 2009 Pearson Education, Inc. All rights reserved.
24
13.4 Example: Handling
DivideByZeroExceptions and
FormatExceptions (Cont.)
13.4.4 Termination Model of Exception Handling
• When a method called in a program or the CLR detects a
problem, the method or the CLR throws an exception.
• The point at which an exception occurs is called the throw point
• If an exception occurs in a try block, program control
immediately transfers to the first catch block matching the
type of the thrown exception.
• After the exception is handled, program control resumes after the
last catch block.
• This is known as the termination model of exception handling.
 2009 Pearson Education, Inc. All rights reserved.
25
13.4 Example: Handling
DivideByZeroExceptions and
FormatExceptions (Cont.)
Common Programming Error 13.1
Logic errors can occur if you assume that after an exception
is handled, control will return to the first statement after the
throw point.
Common Programming Error 13.2
Specifying a comma-separated list of parameters in a catch
block is a syntax error. A catch block can have at most one
parameter.
 2009 Pearson Education, Inc. All rights reserved.
26
13.5 .NET Exception Hierarchy
• In C#, only objects of class Exception and its
derived classes may be thrown and caught.
• Exceptions thrown in other .NET languages can be
caught with the general catch clause.
 2009 Pearson Education, Inc. All rights reserved.
27
13.5 .NET Exception Hierarchy (Cont.)
13.5.1 Class SystemException
• Class Exception is the base class of .NET’s exception
class hierarchy.
• The CLR generates SystemExceptions, derived from
class Exception, which can occur at any point during
program execution.
• If a program attempts to access an out-of-range array
index, the CLR throws an exception of type
IndexOutOfRangeException.
• Attempting to use a null reference causes a
NullReferenceException.
 2009 Pearson Education, Inc. All rights reserved.
28
13.5 .NET Exception Hierarchy (Cont.)
• A catch block can use a base-class type to catch a
hierarchy of related exceptions.
• A catch block that specifies a parameter of type
Exception can catch all exceptions.
• This technique makes sense only if the handling behavior
is the same for a base class and all derived classes.
Common Programming Error 13.3
The compiler issues an error if a catch block that catches a baseclass exception is placed before a catch block for any of that class’s
derived-class types. In this case, the base-class catch block would
catch all base-class and derived-class exceptions, so the derived-class
exception handler would never execute—a possible logic error.
 2009 Pearson Education, Inc. All rights reserved.
29
13.5 .NET Exception Hierarchy (Cont.)
13.5.2 Determining Which Exceptions a Method
Throws
• Search for “Convert.ToInt32 method” in the Index
of the Visual Studio online documentation.
• Select the document entitled Convert.ToInt32
Method (System).
• In the document that describes the method, click the link
ToInt32(String).
• The Exceptions section indicates that method
Convert.ToInt32 throws two exception types.
 2009 Pearson Education, Inc. All rights reserved.
30
13.5 .NET Exception Hierarchy (Cont.)
Software Engineering Observation 13.1
If a method throws exceptions, statements that invoke
the method directly or indirectly should be placed in
try blocks, and those exceptions should be caught and
handled.
 2009 Pearson Education, Inc. All rights reserved.
31
13.6 finally Block
• Programs frequently request and release resources
dynamically.
• Operating systems typically prevent more than one
program from manipulating a file.
• Therefore, the program should close the file
(i.e., release the resource) so other programs can use it.
• If the file is not closed, a resource leak occurs.
 2009 Pearson Education, Inc. All rights reserved.
32
13.6 finally Block (Cont.)
Error-Prevention Tip 13.2
The CLR does not completely eliminate memory leaks.
The CLR will not garbage collect an object until the
program contains no more references to that object and
even then there may be a delay until the memory is
required. Thus, memory leaks can occur if programmers
inadvertently keep references to unwanted objects.
 2009 Pearson Education, Inc. All rights reserved.
33
13.6 finally Block (Cont.)
• Exceptions often occur while processing resources.
• Regardless of whether a program experiences
exceptions, the program should close the file when it
is no longer needed.
• C# provides the finally block, which is guaranteed
to execute regardless of whether an exception occurs.
• This makes the finally block ideal to release
resources from the corresponding try block.
 2009 Pearson Education, Inc. All rights reserved.
34
13.6 finally Block (Cont.)
• Local variables in a try block cannot be accessed in
the corresponding finally block, so variables that
must be accessed in both should be declared before the
try block.
Error-Prevention Tip 13.3
A finally block typically contains code to release
resources acquired in the corresponding try block, which
makes the finally block an effective mechanism for
eliminating resource leaks.
 2009 Pearson Education, Inc. All rights reserved.
35
13.6 finally Block (Cont.)
Performance Tip 13.1
As a rule, resources should be released as soon as they
are no longer needed in a program. This makes them
available for reuse promptly.
Common Programming Error 13.4
Placing the finally block before a catch block is a
syntax error.
 2009 Pearson Education, Inc. All rights reserved.
36
Outline
• The application in Fig. 13.4 demonstrates that the
finally block always executes.
UsingExceptions.cs
1
// Fig. 13.4: UsingExceptions.cs
2
3
// Using finally blocks.
// finally blocks always execute, even when no exception occurs.
4
using System;
5
6
class UsingExceptions
7 {
8
9
10
( 1 of 10 )
static void Main()
{
// Case 1: No exceptions occur in called method
11
12
13
Console.WriteLine( "Calling DoesNotThrowException" );
DoesNotThrowException();
14
15
// Case 2: Exception occurs and is caught in called method
Console.WriteLine( "\nCalling ThrowExceptionWithCatch" );
16
ThrowExceptionWithCatch();
17
18
// Case 3: Exception occurs, but is not caught in called method
19
20
// because there is no catch block.
Console.WriteLine( "\nCalling ThrowExceptionWithoutCatch" );
Main invokes method
DoesNotThrowException.
Main invokes method
ThrowExceptionWithCatch.
Fig. 13.4 | finally blocks always execute, even when no
exception occurs. (Part 1 of 8.)
 2009 Pearson Education,
Inc. All rights reserved.
37
Outline
21
22
// call ThrowExceptionWithoutCatch
23
try
24
25
{
26
} // end try
27
28
29
30
catch
{
Console.WriteLine( "Caught exception from " +
"ThrowExceptionWithoutCatch in Main" );
31
32
33
34
} // end catch
35
36
Console.WriteLine( "\nCalling ThrowExceptionCatchRethrow" );
37
38
// call ThrowExceptionCatchRethrow
try
39
40
41
{
UsingExceptions.cs
( 2 of 10 )
ThrowExceptionWithoutCatch();
// Case 4: Exception occurs and is caught in called method,
// then rethrown to caller.
ThrowExceptionCatchRethrow();
} // end try
Fig. 13.4 | finally blocks always execute, even when no
exception occurs. (Part 2 of 8.)
 2009 Pearson Education,
Inc. All rights reserved.
38
Outline
42
catch
43
{
UsingExceptions.cs
Console.WriteLine( "Caught exception from " +
"ThrowExceptionCatchRethrow in Main" );
44
45
46
} // end catch
47
48
49
50
51
52
} // end method Main
53
54
// no exceptions thrown
static void DoesNotThrowException()
{
// try block does not throw any exceptions
try
{
Console.WriteLine( "In DoesNotThrowException" );
55
56
57
} // end try
catch
58
{
59
60
( 3 of 10 )
Console.WriteLine( "This catch never executes" );
Because the try block does not
throw any exceptions, the catch
block is ignored.
} // end catch
Fig. 13.4 | finally blocks always execute, even when no
exception occurs. (Part 3 of 8.)
 2009 Pearson Education,
Inc. All rights reserved.
39
Outline
61
finally
62
{
63
64
65
66
67
68
69
70
71
72
73
74
75
UsingExceptions.cs
Console.WriteLine( "finally executed in DoesNotThrowException" );
} // end finally
( 4 of 10 )
Console.WriteLine( "End of DoesNotThrowException" );
} // end method DoesNotThrowException
The finally block
always executes.
// throws exception and catches it locally
static void ThrowExceptionWithCatch()
{
// try block throws exception
try
{
Console.WriteLine( "In ThrowExceptionWithCatch" );
76
77
throw new Exception( "Exception in ThrowExceptionWithCatch" );
} // end try
78
79
80
catch ( Exception exceptionParameter )
{
Console.WriteLine( "Message: " + exceptionParameter.Message );
81
} // end catch
The try block
throws an exception.
The catch and finally
blocks execute when the
exception occurs.
Fig. 13.4 | finally blocks always execute, even when no
exception occurs. (Part 4 of 8.)
 2009 Pearson Education,
Inc. All rights reserved.
40
Outline
UsingExceptions.cs
82
finally
83
{
84
85
86
( 5 of 10 )
Console.WriteLine(
"finally executed in ThrowExceptionWithCatch" );
} // end finally
87
88
89
90
Console.WriteLine( "End of ThrowExceptionWithCatch" );
} // end method ThrowExceptionWithCatch
91
// throws exception and does not catch it locally
92
93
94
static void ThrowExceptionWithoutCatch()
{
// throw exception, but do not catch it
95
96
97
try
{
Console.WriteLine( "In ThrowExceptionWithoutCatch" );
98
99
throw new Exception( "Exception in ThrowExceptionWithoutCatch" );
} // end try
The catch and finally
blocks execute when the
exception occurs.
The try block throws
an exception.
Fig. 13.4 | finally blocks always execute, even when no
exception occurs. (Part 5 of 8.)
 2009 Pearson Education,
Inc. All rights reserved.
41
Outline
UsingExceptions.cs
100
101
finally
{
102
103
104
Console.WriteLine( "finally executed in " +
"ThrowExceptionWithoutCatch" );
} // end finally
105
106
107
// unreachable code; logic error
Console.WriteLine( "End of ThrowExceptionWithoutCatch" );
108
} // end method ThrowExceptionWithoutCatch
109
110
111
// throws exception, catches it and rethrows it
static void ThrowExceptionCatchRethrow()
112
113
( 6 of 10 )
The finally block executes
but the exception remains
uncaught until after control
returns to Main.
{
// try block throws exception
114
try
115
116
117
118
{
Console.WriteLine( "In ThrowExceptionCatchRethrow" );
throw new Exception( "Exception in ThrowExceptionCatchRethrow" );
} // end try
The try block throws
an exception.
Fig. 13.4 | finally blocks always execute, even when no
exception occurs. (Part 6 of 8.)
 2009 Pearson Education,
Inc. All rights reserved.
42
Outline
119
catch ( Exception exceptionParameter )
120
121
{
122
123
124
125
126
Console.WriteLine( "Message: " + exceptionParameter.Message );
// rethrow exception for further processing
throw;
UsingExceptions.cs
( 7 of 10 )
The catch block rethrows the
exception, which is then caught
after control returns to Main.
// unreachable code; logic error
127
} // end catch
128
129
finally
{
130
131
132
Console.WriteLine( "finally executed in " +
"ThrowExceptionCatchRethrow" );
} // end finally
The catch and finally
blocks execute when the
exception occurs.
133
134
135
136
// any code placed here is never reached
Console.WriteLine( "End of ThrowExceptionCatchRethrow" );
} // end method ThrowExceptionCatchRethrow
137 } // end class UsingExceptions
Fig. 13.4 | finally blocks always execute, even when no
exception occurs. (Part 7 of 8.)
 2009 Pearson Education,
Inc. All rights reserved.
43
Calling DoesNotThrowException
In DoesNotThrowException
finally executed in DoesNotThrowException
End of DoesNotThrowException
Calling ThrowExceptionWithCatch
In ThrowExceptionWithCatch
Message: Exception in ThrowExceptionWithCatch
finally executed in ThrowExceptionWithCatch
End of ThrowExceptionWithCatch
Calling ThrowExceptionWithoutCatch
In ThrowExceptionWithoutCatch
finally executed in ThrowExceptionWithoutCatch
Caught exception from ThrowExceptionWithoutCatch in Main
Calling ThrowExceptionCatchRethrow
In ThrowExceptionCatchRethrow
Message: Exception in ThrowExceptionCatchRethrow
finally executed in ThrowExceptionCatchRethrow
Caught exception from ThrowExceptionCatchRethrow in Main
Fig. 13.4 | finally blocks always execute, even when no
exception occurs. (Part 8 of 8.)
 2009 Pearson Education,
Inc. All rights reserved.
44
Common Programming Error 13.5
It is a compilation error if the argument of a
throw—an exception object—is not of class
Exception or one of its derived classes.
Common Programming Error 13.6
Throwing an exception from a finally block can be
dangerous. If an uncaught exception is awaiting processing
when the finally block executes, and the finally block
throws a new exception that is not caught in the finally
block, the first exception is lost, and the new exception is
passed to the next enclosing try block.
 2009 Pearson Education,
Inc. All rights reserved.
45
Error-Prevention Tip 13.4
When placing code that can throw an exception in a
finally block, always enclose the code in a try
statement that catches the appropriate exception types.
This prevents the loss of any uncaught and rethrown
exceptions that occur before the finally block executes.
Software Engineering Observation 13.2
Do not place try blocks around every statement that
might throw an exception—this can make programs
difficult to read. It’s better to place one try block around
a significant portion of code, and follow this try block
with catch blocks that handle each possible exception.
Then follow the catch blocks with a single finally
block. Separate try blocks should be used when it is
important to distinguish between multiple statements that
can throw the same exception type.
 2009 Pearson Education,
Inc. All rights reserved.
46
13.6 finally Block (Cont.)
• The using statement simplifies writing code in
which you obtain a resource.
• The general form of a using statement is:
using ( ExampleObject e = new ExampleObject() )
{
e.SomeMethod();
}
 2009 Pearson Education, Inc. All rights reserved.
47
13.6 finally Block (Cont.)
• The using statement code is equivalent to
{
ExampleObject e = new ExampleObject();
try
{
e.SomeMethod();
}
finally
{
if ( e != null )
( ( IDisposable ) e ).Dispose();
}
}
 2009 Pearson Education, Inc. All rights reserved.
48
13.7 Exception Properties
• Class Exception’s properties are used to formulate
error messages indicating a caught exception.
– Property Message stores the error message associated with an
Exception object.
– Property StackTrace contains a string that represents the
method-call stack.
 2009 Pearson Education, Inc. All rights reserved.
49
13.7 Exception Properties (Cont.)
Error-Prevention Tip 13.5
If the program database (PDB) file that contains the
debugging information for a method is accessible to the
IDE, the stack trace also includes line numbers; the first
line number indicates the throw point, and subsequent
line numbers indicate the locations from which the
methods in the stack trace were called. PDB files are
created by the IDE to maintain the debugging
information for your projects.
 2009 Pearson Education, Inc. All rights reserved.
50
13.7 Exception Properties (Cont.)
• When an exception occurs, a programmer might use a
different error message or indicate a new exception type.
• The original exception object is stored in the
InnerException property.
 2009 Pearson Education, Inc. All rights reserved.
51
13.7 Exception Properties (Cont.)
• Class Exception provides other properties:
– HelpLink specifies the location of a help file that describes the
problem.
– Source specifies the name of the application or object that
caused the exception.
– TargetSite specifies the method where the exception
originated.
 2009 Pearson Education, Inc. All rights reserved.
52
Outline
• Our next example (Fig. 13.5) demonstrates properties
of class Exception.
Properties.cs
1
2
// Fig. 13.5: Properties.cs
// Stack unwinding and Exception class properties.
3
4
5
// Demonstrates using properties Message, StackTrace and InnerException.
using System;
6
7
8
9
class Properties
{
static void Main()
{
10
11
12
13
// call Method1; any Exception generated is caught
// in the catch block that follows
try
{
14
15
Method1();
} // end try
( 1 of 5 )
Fig. 13.5 | Stack unwinding and Exception class properties. (Part 1 of 5.)
 2009 Pearson Education,
Inc. All rights reserved.
53
Outline
16
catch ( Exception exceptionParameter )
17
{
18
// output the string representation of the Exception, then output
19
20
// properties InnerException, Message and StackTrace
Console.WriteLine( "exceptionParameter.ToString: \n{0}\n",
21
22
23
24
25
Properties.cs
( 2 of 5 )
exceptionParameter );
Console.WriteLine( "exceptionParameter.Message: \n{0}\n",
exceptionParameter.Message );
Console.WriteLine( "exceptionParameter.StackTrace: \n{0}\n",
exceptionParameter.StackTrace );
26
27
28
29
Console.WriteLine( "exceptionParameter.InnerException: \n{0}\n",
exceptionParameter.InnerException );
} // end catch
} // end method Main
30
31
// calls Method2
32
33
static void Method1()
{
34
35
36
Method2();
} // end method Method1
Outputting properties of
class Exception.
Method1 and Method2 are
added to the method stack, and
then unwind when they do not
catch Method3’s exception.
Fig. 13.5 | Stack unwinding and Exception class properties. (Part 2 of 5.)
 2009 Pearson Education,
Inc. All rights reserved.
54
Outline
37
// calls Method3
Properties.cs
38
39
40
41
static void Method2()
{
Method3();
} // end method Method2
( 3 of 5 )
42
43
44
// throws an Exception containing an InnerException
static void Method3()
45
46
47
{
// attempt to convert string to int
try
48
49
50
51
{
52
53
54
{
55
56
57
Method1 and Method2 are
added to the method stack, and
then unwind when they do not
catch Method3’s exception.
Convert.ToInt32( "Not an integer" );
} // end try
catch ( FormatException formatExceptionParameter )
// wrap FormatException in new Exception
throw new Exception( "Exception occurred in Method3",
formatExceptionParameter );
} // end catch
} // end method Method3
Method3 catches then
rethrows the exception.
58 } // end class Properties
Fig. 13.5 | Stack unwinding and Exception class properties. (Part 3 of 5.)
 2009 Pearson Education,
Inc. All rights reserved.
55
Outline
exceptionParameter.ToString:
Properties.cs
System.Exception: Exception occurred in Method3 --->
System.FormatException: Input string was not in a correct format.
( 4 of 5 )
at System.Number.StringToNumber(String str, NumberStyles options,
N u m b e r B u f f e r & n u m b e r , N u m b e rF o r m a t I n f o i n f o , B o o l e a n p a r s e D e c i m a l )
at System.Number.ParseInt32(String s, NumberStyles style,
NumberFormatInfo info)
at System.Convert.ToInt32(String value)
a t P r o p e r t i e s . M e t h o d 3 ( ) i n C :\ e x a m p l e s \ c h 1 3 \ F i g 1 3 _ 0 5 \ P r o p e r t i e s \
Properties\Properties.cs:line 49
--- End of inner exception stack trace --a t P r o p e r t i e s . M e t h o d 3 ( ) i n C :\ e x a m p l e s \ c h 1 3 \ F i g 1 3 _ 0 5 \ P r o p e r t i e s \
Properties\Properties.cs:line 54
a t P r o p e r t i e s . M e t h o d 2 ( ) i n C :\ e x a m p l e s \ c h 1 3 \ F i g 1 3 _ 0 5 \ P r o p e r t i e s \
Properties\Properties.cs:line 40
a t P r o p e r t i e s . M e t h o d 1 ( ) i n C :\ e x a m p l e s \ c h 1 3 \ F i g 1 3 _ 0 5 \ P r o p e r t i e s \
Properties\Properties.cs:line 34
a t P r o p e r t i e s . M a i n ( ) i n C :\ e x a m p l e s \ c h 1 3 \ F i g 1 3 _ 0 5 \ P r o p e r t i e s \
Properties\Properties.cs:line 14
Fig. 13.5 | Stack unwinding and Exception class properties. (Part 4 of 5.)
 2009 Pearson Education,
Inc. All rights reserved.
56
Outline
Properties.cs
exceptionParameter.Message:
Exception occurred in Method3
( 5 of 5 )
exceptionParameter.StackTrace:
at Properties.Method3() in C:\examples\ch13\Fig13_05\Properties\
Properties\Properties.cs:line 54
at Properties.Method2() in C:\examples\ch13\Fig13_05\Properties\
Properties\Properties.cs:line 40
at Properties.Method1() in C:\examples\ch13\Fig13_05\Properties\
Properties\Properties.cs:line 34
at Properties.Main() in C:\examples\ch13\Fig13_05\Properties\
Properties\Properties.cs:line 14
exceptionParameter.InnerException:
System.FormatException: Input string was not in a correct format.
at System.Number.StringToNumber(String str, NumberStyles options,
NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal)
at System.Number.ParseInt32(String s, NumberStyles style,
NumberFormatInfo info)
at System.Convert.ToInt32(String value)
at Properties.Method3() in C:\examples\ch13\Fig13_05\Properties\
Properties\Properties.cs:line 49
Fig. 13.5 | Stack unwinding and Exception class properties. (Part 5 of 5.)
 2009 Pearson Education,
Inc. All rights reserved.
57
13.7 Exception Properties (Cont.)
• The method called most recently appears at the top of the
stack; the first method (Main) appears at the bottom.
• The StackTrace represents the state of the method-call
stack at the throw point.
• The inner-exception information includes the inner
exception stack trace.
Error-Prevention Tip 13.6
When catching and rethrowing an exception, provide additional
debugging information in the rethrown exception. To do so, create an
Exception object containing more specific debugging information,
then pass the original caught exception to the new exception object’s
constructor to initialize the InnerException property.
 2009 Pearson Education, Inc. All rights reserved.
58
13.8 User-Defined Exception Classes
• In some cases, you might create exception classes
specific to the problems that occur in your programs.
• User-defined exception classes should derive directly
or indirectly from class Exception of namespace
System.
• Exceptions should be documented so that other
developers will know how to handle them.
 2009 Pearson Education, Inc. All rights reserved.
59
13.8 User-Defined Exception Classes
(Cont.)
• User-defined exceptions should define three
constructors:
– a parameterless constructor
– a constructor that receives a string argument
(the error message)
– a constructor that receives a string argument and an
Exception argument (the error message and the inner
exception object)
 2009 Pearson Education, Inc. All rights reserved.
60
13.8 User-Defined Exception Classes
(Cont.)
Good Programming Practice 13.1
Associating each type of malfunction with an
appropriately named exception class improves
program clarity.
Software Engineering Observation 13.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.
 2009 Pearson Education, Inc. All rights reserved.
61
Outline
• Class NegativeNumberException (Fig. 13.6)
represents exceptions that occur when a program performs an
illegal operation on a negative number.
NegativeNumber
Exception.cs
( 1 of 2 )
1
// Fig. 13.6: NegativeNumberException.cs
2
// NegativeNumberException represents exceptions caused by
3
4
// illegal operations performed on negative numbers.
using System;
5
6
namespace SquareRootTest
7
8
9
{
class NegativeNumberException : Exception
{
10
// default constructor
11
public NegativeNumberException()
12
13
14
15
16
Inheriting from class
Exception.
: base( "Illegal operation for a negative number" )
Parameterless constructor.
{
// empty body
} // end default constructor
Fig. 13.6 | NegativeNumberException represents exceptions caused by
illegal operations performed on negative numbers. (Part 1 of 2.)
 2009 Pearson Education,
Inc. All rights reserved.
62
Outline
NegativeNumber
Exception.cs
17
18
// constructor for customizing error message
public NegativeNumberException( string messageValue )
: base( messageValue )
19
20
21
{
22
23
24
25
} // end one-argument constructor
26
public NegativeNumberException( string messageValue,
// empty body
Exception inner )
28
: base( messageValue, inner )
32
Constructor with a single
argument (the Message).
// constructor for customizing the exception's error
// message and specifying the InnerException object
27
29
30
31
( 2 of 2 )
Constructor with two
arguments (the Message
and InnerException).
{
// empty body
} // end two-argument constructor
} // end class NegativeNumberException
33 } // end namespace SquareRootTest
Fig. 13.6 | NegativeNumberException represents exceptions caused by
illegal operations performed on negative numbers. (Part 2 of 2.)
 2009 Pearson Education,
Inc. All rights reserved.
63
Outline
• Class SquareRootForm (Fig. 13.7) demonstrates
our user-defined exception class.
SquareRootTest.cs
( 1 of 4 )
1
// Fig. 13.7: SquareRootTest.cs
2
3
4
// Demonstrating a user-defined exception class.
using System;
using System.Windows.Forms;
5
6
namespace SquareRootTest
7
8
9
10
11
12
13
14
{
public partial class SquareRootForm : Form
{
public SquareRootForm()
{
InitializeComponent();
} // end constructor
Fig. 13.7 | Demonstrating a user-defined exception class. (Part 1 of 4.)
 2009 Pearson Education,
Inc. All rights reserved.
64
Outline
15
16
// computes square root of parameter; throws
// NegativeNumberException if parameter is negative
17
18
19
public double SquareRoot( double value )
{
// if negative operand, throw NegativeNumberException
20
if ( value < 0 )
21
22
23
throw new NegativeNumberException(
"Square root of negative number not permitted" );
else
24
25
26
27
return Math.Sqrt( value ); // compute square root
} // end method SquareRoot
28
29
30
31
private void squareRootButton_Click( object sender, EventArgs e )
{
outputLabel.Text = ""; // clear OutputLabel
32
33
34
35
36
37
// obtain user input, convert to double, calculate square root
SquareRootTest.cs
( 2 of 4 )
If the numeric value that the user
enters is negative, SquareRoot
throws a NegativeNumberException.
SquareRoot invokes Math’s
Sqrt method.
// catch any NegativeNumberException thrown
try
{
double result =
SquareRoot( Convert.ToDouble( inputTextBox.Text ) );
Fig. 13.7 | Demonstrating a user-defined exception class. (Part 2 of 4.)
 2009 Pearson Education,
Inc. All rights reserved.
65
Outline
38
outputLabel.Text = result.ToString();
39
} // end try
40
41
42
catch ( FormatException formatExceptionParameter )
{
MessageBox.Show( formatExceptionParameter.Message,
43
44
45
"Invalid Number Format", MessageBoxButtons.OK,
MessageBoxIcon.Error );
} // end catch
46
47
48
catch ( NegativeNumberException
negativeNumberExceptionParameter )
{
49
50
51
52
MessageBox.Show( negativeNumberExceptionParameter.Message,
"Invalid Operation", MessageBoxButtons.OK,
MessageBoxIcon.Error );
} // end catch
SquareRootTest.cs
( 3 of 4 )
Catching and handling a
NegativeNumber
Exception.
53
} // end method squareRootButton_Click
54
} // end class SquareRootForm
55 } // end namespace SquareRootTest
Fig. 13.7 | Demonstrating a user-defined exception class. (Part 3 of 4.)
 2009 Pearson Education,
Inc. All rights reserved.
66
Outline
a) Calculating an integer square root
b) Calculating a double square root
SquareRootTest.cs
( 4 of 4 )
c) Attempting a negative square root
d) Error message displayed
Fig. 13.7 | Demonstrating a user-defined exception class. (Part 4 of 4.)
 2009 Pearson Education,
Inc. All rights reserved.
Descargar

1 - Philadelphia University