finally
block at the end of a
try
/
catch
sequence. The general form of a
try
/
catch
that includes
finally
is shown here:
try {
// block of code to monitor for errors
}
catch (
ExcepType1 exOb
) {
// handler for
ExcepType1
}
catch (
ExcepType2 exOb
) {
// handler for
ExcepType2
}
.
.
.
fi nally {
// fi nally code
}
The
finally
block will be executed whenever execution leaves a
try/catch
block, no
matter what conditions cause it. That is, whether the
try
block ends normally, or because
of an exception, the last code executed is that defined by
finally
. The
finally
block is also
executed if any code within the
try
block or any of its
catch
blocks returns from the method.
Here is an example of
finally
:
// Use finally.
using System;
class UseFinally {
public static void GenException(int what) {
www.freepdf-books.com
350
P a r t I :
T h e C # L a n g u a g e
int t;
int[] nums = new int[2];
Console.WriteLine("Receiving " + what);
try {
switch(what) {
case 0:
t = 10 / what; // generate div-by-zero error
break;
case 1:
nums[4] = 4; // generate array index error
break;
case 2:
return; // return from try block
}
}
catch (DivideByZeroException) {
Console.WriteLine("Can't divide by Zero!");
return; // return from catch
}
catch (IndexOutOfRange Exception) {
Console.WriteLine("No matching element found.");
}
finally {
Console.WriteLine("Leaving try.");
}
}
}
class FinallyDemo {
static void Main() {
for(int i=0; i < 3; i++) {
UseFinally.GenException(i);
Console.WriteLine();
}
}
}
Here is the output produced by the program:
Receiving 0
Can't divide by Zero!
Leaving try.
Receiving 1
No matching element found.
Leaving try.
Receiving 2
Leaving try.
As the output shows, no matter how the
try
block is exited, the
finally
block executed.
www.freepdf-books.com
PART I
C h a p t e r 1 3 :
E x c e p t i o n H a n d l i n g
351
PART IPART I
One other point: Syntactically, when a
finally
block follows a
try
block, no
catch
clauses
are technically required. Thus, you can have a
try
followed by a
finally
with no
catch
clauses. In this case, the
finally
block is executed when the
try
exits, but no exceptions
are handled.
A Closer Look at the Exception Class
Up to this point, we have been catching exceptions, but we haven’t been doing anything
with the exception object itself. As explained earlier, a
catch
clause allows you to specify an
exception type
and
a variable. The variable receives a reference to the exception object. Since
all exceptions are derived from
Exception
, all exceptions support the members defined by
Exception
. Here we will examine several of its most useful members and constructors, and
put the exception variable to use.
Exception
defines several properties. Three of the most interesting are
Message
,
StackTrace
, and
TargetSite
. All are read-only.
Message
contains a string that describes the
nature of the error.
StackTrace
contains a string that contains the stack of calls that lead to
the exception.
TargetSite
obtains an object that specifies the method that generated the
exception.
Exception
also defines several methods. One that you will often use is
ToString( )
,
which returns a string that describes the exception.
ToString( )
is automatically called
when an exception is displayed via
WriteLine( )
, for example.
The following program demonstrates these properties and this method:
// Using Exception members.
using System;
class ExcTest {
public static void GenException() {
int[] nums = new int[4];
Console.WriteLine("Before exception is generated.");
// Generate an index out-of-bounds exception.
for(int i=0; i < 10; i++) {
nums[i] = i;
Console.WriteLine("nums[{0}]: {1}", i, nums[i]);
}
Console.WriteLine("this won't be displayed");
}
}
class UseExcept {
static void Main() {
try {
ExcTest.GenException();
}
catch (IndexOutOfRangeException exc) {
www.freepdf-books.com
352
P a r t I :
T h e C # L a n g u a g e
Console.WriteLine("Standard message is: ");
Console.WriteLine(exc); // calls ToString()
Console.WriteLine("Stack trace: " + exc.StackTrace);
Console.WriteLine("Message: " + exc.Message);
Console.WriteLine("TargetSite: " + exc.TargetSite);
}
Console.WriteLine("After catch block.");
}
}
The output from this program is shown here:
Before exception is generated.
nums[0]: 0
nums[1]: 1
nums[2]: 2
nums[3]: 3
Standard message is:
System.IndexOutOfRangeException: Index was outside the bounds of the array.
at ExcTest.GenException()
at UseExcept.Main()
Stack trace: at ExcTest.GenException()
at UseExcept.Main()
Message: Index was outside the bounds of the array.
TargetSite: Void GenException()
After catch block.
Exception
defi nes the following four constructors:
public Exception( )
public Exception(string
str
)
public Exception(string
str
, Exception
inner
)
protected Exception(System.Runtime.Serialization.SerializationInfo
si
,
System.Runtime.Serialization.StreamingContext
sc
)
The first is the default constructor. The second specifies the string associated with the
Message
property associated with the exception. The third specifies what is called an
inner
exception.
It is used when one exception gives rise to another. In this case,
inner
specifies the
first exception, which will be null if no inner exception exists. (The inner exception, if it
exists, can be obtained from the
InnerException
property defined by
Exception
.) The last
constructor handles exceptions that occur remotely and require deserialization.
One other point: In the fourth
Exception
constructor shown above, notice that the types
SerializationInfo
and
StreamingContext
are contained in the
System.Runtime.Serialization
namespace.
Commonly Used Exceptions
The
System
namespace defines several standard, built-in exceptions. All are derived from
SystemException
since they are generated by the CLR when runtime errors occur. Several
of the more commonly used standard exceptions are shown in Table 13-1.
www.freepdf-books.com
Do'stlaringiz bilan baham: |