Chapter 7 Exception Handling
Common Language Runtime (CLR) has a major advantage in that exception handling is cross-language standardized. An exception thrown in C # can be handled in Visual Basic. There are no HRESULTs or ISupportErrorInfo interfaces.
Despite the wide coverage of cross-language Exception Handling, this chapter focuses entirely on C # exception handling. To change the overflow processing behavior of the compiler, the interesting thing begins: You have handled the exception. You need to add more methods and then cause the exceptions you have created.
7.1 checked and unchecked statements
When you perform an operation, the calculation result may be out of the valid range of the Data Type of the result variable. This situation is called overflow. Depending on different programming languages, you will be notified in some way-or you will not be notified at all. (Do C ++ programmers sound familiar ?)
So, how does C # handle overflow? To find out its default behavior, see the factorial example I mentioned earlier in this book. (For convenience, the previous example is given again in listing 7.1)
Listing 7.1 calculates the factorial of a number
1: using System;
2:
3: class Factorial
4 :{
5: public static void Main (string [] args)
6 :{
7: long nFactorial = 1;
8: long nComputeTo = Int64.Parse (args [0]);
9:
10: long nCurDig = 1;
11: for (nCurDig = 1; nCurDig <= nComputeTo; nCurDig ++)
12: nFactorial * = nCurDig;
13:
14: Console. WriteLine ("{0 }! Is {1} ", nComputeTo, nFactorial );
15 :}
16 :}
When you execute a program using a command line like this
Factorial 2000
The result is 0 and nothing happens. Therefore, imagine C # To handle overflow silently without explicitly warning you that it is safe.
You can change this behavior by allowing overflow verification at the statement level for the entire application (switched by the compiler. The following two sections solve one problem
Case.
7.1.1 configure the compiler for overflow Verification
If you want to control overflow verification for the entire application, the C # compiler setting is exactly what you are looking. By default, overflow verification is disabled. Be clear
And run the following compiler command:
Csc factorial. cs/checked +
Now when you use the 2000 parameter to execute an application, CLR notifies you of an overflow exception (see Figure 7.1 ).
Figure 7.1 overflow exception is allowed, and the factorial code generates an exception.
Press OK to exit the dialog box to reveal the exception information:
Exception occurred: System. OverflowException
At Factorial. Main (System. String [])
Now you know that the overflow condition causes a System. OverflowException exception. Next, how to capture and
Handle exceptions?
7.1.2 syntax overflow check
If you do not want to allow overflow verification for the entire application and only allow verification for some code segments, you may be comfortable. For such occasions, you may
The verification statement is used as shown in single 7.2.
Listing 7.2 overflow verification in factorial calculation
1: using System;
2:
3: class Factorial
4 :{
5: public static void Main (string [] args)
6 :{
7: long nFactorial = 1;
8: long nComputeTo = Int64.Parse (args [0]);
9:
10: long nCurDig = 1;
11:
12: for (nCurDig = 1; nCurDig <= nComputeTo; nCurDig ++)
13: checked {nFactorial * = nCurDig ;}
14:
15: Console. WriteLine ("{0 }! Is {1} ", nComputeTo, nFactorial );
16 :}
17 :}
Even if you use the flag checked-to compile the code, overflow verification will still check the multiplication implementation in row 13th. The error message is consistent.
The statement that shows the opposite behavior is not verified (unchecked ). Even if overflow verification is allowed (the checked + flag is added to the compiler ),
The Code included in the unchecked statement will not cause overflow exceptions:
Unchecked
{
NFactorial * = nCurDig;
}
7.2 Exception Handling statement
Since you know how to generate an exception (you will find more methods, believe me), there are still problems with how to handle it. If you are a C ++
WIN32 programmers must be familiar with SEH (Structure Exception Handling ). You will find comfort from this. The commands in C # are almost the same, and they are similar
Operation.
The following three sections introduce C # s exception-handling statements:
The following three sections describe C # Exception Handling statements:
. Catch exceptions with try-catch
. Use try-finally to clear exceptions
. Use try-catch-finally to handle all exceptions
7.2.1 catch exceptions using try and catch
You will certainly be very interested in one thing-do not prompt the user for the annoying exception message, so that your application can continue to execute. To do this, you
The exception must be caught (handled.
In this way, try and catch are used. Try contains statements that may generate exceptions, while catch processes an exception. If an exception exists. Clear
Use try and catch for OverflowException in single 7.3 to handle exceptions.
Listing 7.3 capturing OverflowException exceptions caused by Factorial Calculation
1: using System;
2:
3: class Factorial
4 :{
5: public static void Main (string [] args)
6 :{
7: long nFactorial = 1, nCurDig = 1;
8: long nComputeTo = Int64.Parse (args [0]);
9:
10: try
11 :{
12: checked
13 :{
14: for (; nCurDig <= nComputeTo; nCurDig ++)
15: nFactorial * = nCurDig;
16 :}
17 :}
18: catch (OverflowException oe)
19 :{
20: Console. WriteLine ("Computing {0} caused an overflow exception", nComputeTo );
21: return;
22 :}
23:
24: Console. WriteLine ("{0 }! Is {1} ", nComputeTo, nFactorial );
25 :}
26 :}
For clarity, I have extended some code segments, and I also ensure that exceptions are generated by the checked statement, even when you forget the compiler settings.
As you can see, exception handling is not troublesome. All you have to do is: Include the code that is prone to exceptions in the try statement, and then catch the exception. The exception is
In this example, it is of the OverflowException type. No matter when an exception is thrown, the code in the catch segment must be properly processed.
If you do not know which exception will be expected, but want to be in a safe state, simply ignore the exception type.
Try
{
...
}
Catch
{
...
}
However, in this way, you cannot obtain access to the exception object, which contains important error information. The General Exception Handling Code is as follows:
Try
{
...
}
Catch (System. Exception e)
{
...
}
Note that you cannot use the ref or out modifier to pass the e object to a method or assign a different value to it.
7.2.2 use try and finally to clear exceptions
If you are more concerned with clearing, rather than error handling, try and finally will enjoy it. It not only suppresses error messages, but also contains
Code in the finally block will still be executed after an exception is thrown.
Although the program is not terminated normally, you can obtain a message for the user, as shown in listing 7.4.
Listing 7.4 Exception Handling in finally statements
1: using System;
2:
3: class Factorial
4 :{
5: public static void Main (string [] args)
6 :{
7: long nFactorial = 1, nCurDig = 1;
8: long nComputeTo = Int64.Parse (args [0]);
9: bool bAllFine = false;
10:
11: try
12 :{
13: checked
14 :{
15: for (; nCurDig <= nComputeTo; nCurDig ++)
16: nFactorial * = nCurDig;
17 :}
18: bAllFine = true;
19 :}
20: finally
21 :{
22: if (! BAllFine)
23: Console. WriteLine ("Computing {0} caused an overflow exception", nComputeTo );
24: else
25: Console. WriteLine ("{0 }! Is {1} ", nComputeTo, nFactorial );
26 :}
27 :}
28 :}
By detecting this code, you may guess that