> Seventh, exception Handling (Rainbow translation) (from heavy particle space)

Source: Internet
Author: User
Tags empty error handling exception handling finally block goto implement switches valid
<< Show c#>> Seventh chapter exception handling (Rainbow translation)

Source: http://www.informit.com/matter/ser0000002

Body:

Seventh Chapter exception Handling

One of the great advantages of the common language runtime (CLR) is that exception handling is standardized across languages. An exception that is thrown in C # can be handled in the Visual Basic client. There is no longer a hresults or ISupportErrorInfo interface.
Although the coverage of cross language exception handling is extensive, this chapter focuses entirely on C # exception handling. You slightly change the compiler's overflow behavior, and then the interesting thing begins: you handle the exception. To add more means, then raise the exception you created.

7.1 Checksum (checked) and non-checksum (unchecked) statements
When you perform an operation, it is possible that the calculated result is beyond the valid range of the result variable data type. This situation is called overflow, and depending on the programming language, you will be notified in some way-or not at all. (Does C + + programmers sound familiar?) )
So, how does C # handle overflow? To find out its default behavior, see the example of factorial I mentioned earlier in this book. (For your convenience, the previous example is shown 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 use the command line to execute a program like this
Factorial 2000

The result was 0 and nothing happened. Therefore, it is safe to assume that C # silently handles overflow situations without explicitly warning you.
You can change this behavior by allowing overflow checksums for the entire application (the compiler switches) or at the statement level. The following two sections address one scenario separately.
7.1.1 set compiler for overflow checksum
If you want to control overflow checksums for the entire application, the C # compiler settings selection is exactly what you're looking for. By default, overflow checksums are disabled. To explicitly ask for it, run the following compiler command:
CSC factorial.cs/checked+

Now when you execute the application with the 2000 parameter, the CLR notifies you of the overflow exception (see Figure 7.1).

Figure 7.1 Allows an overflow exception, and the factorial code produces an exception.

Press OK to leave the dialog box to reveal the exception information:
Exception occurred:System.OverflowException
At Factorial.main (system.string[])

Now you understand that the overflow condition throws a System.OverflowException exception. In the next section, how do we capture and process the exception after we complete the grammar check?
7.1.2 Syntax Overflow checksum
If you do not want to allow overflow checksums for the entire application, you may be comfortable with only certain code snippets that allow checksums. For this occasion, you might use a checksum statement as shown in Listing 7.2.

Listing 7.2 The overflow checksum 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 compile the code using the flag checked-, in line 13th, the overflow checksum will still check the multiplication implementation. The error message remains consistent.

Statements that display the opposite behavior are not checksums (unchecked). Even if overflow checksums are allowed (add checked+ flags to the compiler), the code enclosed by the unchecked statement will not throw an overflow exception:

Unchecked
{
Nfactorial *= Ncurdig;
}



7.2 Exception Handling Statements
Now that you know how to create an exception (you'll find more ways to believe me), there's still a problem with how to deal with it. If you are a C + + WIN32 programmer, you must be familiar with SEH (structural exception handling). You will find solace in the fact that the commands in C # are almost the same, and they work in a similar way.

The following three sections introduce C # ' s exception-handling statements:
The following three sections describe the C # exception handling statements:

。 Catching Exceptions with Try-catch
。 Clear exceptions with try-finally
。 Use try-catch-finally to handle all exceptions

7.2.1 use try and catch to catch exceptions
You will be very interested in one thing-don't prompt the user with that annoying exception message so your application can continue. To do so, you must capture (handle) the exception.
The statements used in this way are try and catch. A try contains a statement that may produce an exception, and a catch handles an exception if there is an exception. Listing 7.3 implements exception handling for OverflowException with try and catch.

Listing 7.3 captures the OverflowException exception thrown 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:}

To illustrate, I've extended some code snippets, and I guarantee that the exception is 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 code that is prone to generating exceptions in the Try statement, and then catch the exception, which is the OverflowException type in this example. Regardless of when an exception is raised, the code in the Catch section notices the appropriate processing.
Simply ignore the type of exception if you do not know in advance which one is expected and still want to be in a safe state.

Try
{
...
}
Catch
{
...
}

However, in this way, you cannot gain access to the object of the exception, which contains important error messages. Generalized exception handling code like this:

Try
{
...
}
catch (System.Exception e)
{
...
}

Note that you cannot pass the E object to a method with a ref or out modifier, nor can you assign it a different value.

7.2.2 use try and finally to clear exceptions
If you are more concerned with purging than error handling, try and finally will get your liking. Not only does it suppress error messages, but all code contained in a finally block is still executed after the exception is raised.
Although the program terminates abnormally, you can also get a message for the user, as shown in Listing 7.4.

Listing 7.4 Handling Exceptions in a finally statement

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 the code, you might guess that finally, even without throwing exception handling, it will be executed. This is true--the code in finally is always executed, regardless of the exception condition. In order to illustrate how to provide some meaningful information to the user in two situations, I introduced the new variable ballfine. Ballfine tells the finally paragraph whether it was invoked because of an exception or simply because the calculation was completed successfully.
As a SEH programmer, you might wonder if there is a statement equivalent to a __leave statement that works well in C + +. If you are not aware of this, the __leave statement in C + + is used to prematurely terminate the execution code in the try segment and immediately jump to the finally segment.
Bad news, there are no __leave statements in C #. However, the code in Listing 7.5 shows a scenario that you can implement.

Listing 7.5 jumps from the try statement to the finally statement

1:using System;
2:
3:class Jumptest
4: {
5:public static void Main ()
6: {
7:try
8: {
9:console.writeline ("Try");
10:goto __leave;
11:}
12:finally
13: {
14:console.writeline ("finally");
15:}
16:
__leave:
18:console.writeline ("__leave");
19:}
20:}


When the application is running, the output results are

Try
Finally
__leave

A goto statement cannot exit a finally segment. Even the goto statement is placed in a try statement segment, or the control is immediately returned to the finally segment. As a result, Goto simply leaves the try phrase and jumps to the finally segment. The __leave tag cannot be reached until the code in finally is finished running. In this way, you can imitate the __leave statements used in SEH.
By the way, you may suspect that the Goto statement is ignored because it is the last statement in the Try statement, and the control is automatically transferred to finally. To prove that this is not the case, try to place the Goto statement before the Console.WriteLine method call. Although you get a compiler warning for unreachable code, you will see that the goto statement is actually executed and there is no output generated for the try string.

7.2.3 use try-catch-finally to handle all exceptions
The most likely way for an application is to merge the previous two error-handling techniques-to catch errors, to purge, and to continue to execute the application. All you have to do is use try, catch, and finally statements in the error handling code. Listing 7.6 shows the way to handle 0 error removal.

Listing 7.6 implements multiple catch statements

1:using System;
2:
3:class Catchit
4: {
5:public static void Main ()
6: {
7:try
8: {
9:int Nthezero = 0;
10:int nresult = 10/nthezero;
11:}
12:catch (DivideByZeroException Divex)
13: {
14:console.writeline ("Divide by Zero occurred!");
15:}
16:catch (Exception Ex)
17: {
18:console.writeline ("Some other exception");
19:}
20:finally
21: {
22:}
23:}
24:}

The trick for this example is that it contains multiple catch statements. The first captures a more likely dividebyzeroexception exception, while the second catch statement handles all the remaining exceptions by capturing the normal exception.
You must always first catch a particular exception, followed by an ordinary exception. What happens if you don't catch an exception in this order? The code in Listing 7.7 has a description.

Listing 7.7 A Catch statement that is not in the right order

1:try
2: {
3:int Nthezero = 0;
4:int nresult = 10/nthezero;
5:}
6:catch (Exception Ex)
7: {
8:console.writeline ("Exception" + ex.tostring ());
9:}
10:catch (DivideByZeroException Divex)
11: {
12:console.writeline ("Never going to");
13:}


The compiler catches a small error and looks like this to report the error:
Wrongcatch.cs (10,9): Error cs0160:a previous catch clause already
Catches all exceptions to this or a super type (' System.Exception ')

Finally, I have to report a disadvantage (or difference) between CLR exceptions and SEH: There is no equivalent of a exception_continue_execution identifier, which is useful in SEH exception filters. Basically, Exception_continue_execution allows you to rerun the code fragment that is responsible for the exception. Before you rerun, you have the opportunity to change variables, and so on. My personal favorite technique is to use Access violation exceptions to implement memory allocations as needed.


7.3 Throwing an exception
When you have to catch an exception, others must first be able to throw an exception. And, not only can other people be able to trigger, you can also be responsible for triggering. It's fairly simple:

throw new ArgumentException ("Argument can ' t be 5");
All you need is a throw statement and an appropriate exception class. I have selected an exception for this example from the list provided in Table 7.1.

Table 7.1 Runtime provided standard exceptions


Exception type description

Exception the base class for all exception objects
base class for all errors generated by the SystemException runtime
IndexOutOfRangeException when the subscript of an array runs out of range
NullReferenceException is thrown when an empty object is referenced
InvalidOperationException when the invocation of the opposing method is not valid for the object's current state, it is raised by some methods
ArgumentException the base class for all parameter exceptions
ArgumentNullException when the argument is empty (not allowed), the method is thrown by the
ArgumentOutOfRangeException the method is thrown when the argument is not within a given range
Interopexception the base class for exceptions that target or occur in the environment outside the CLR
COMException exceptions that contain HRESULT information for COM classes
exception of SEHException encapsulation Win32 Structure exception handling information

However, you don't have to create a new exception inside a catch statement if you have an exception that is randomly disposed of. Perhaps none of the exceptions in table 7.1 meet your particular requirements-why not create a new exception? In the upcoming section, these two topics are covered.

7.3.1 to throw the exception again
When you are inside a catch statement, you may decide to raise an exception that is currently being processed, leaving further processing to some external try-catch statements. An example of this method is shown in Listing 7.8.

Listing 7.8 to throw a new exception

1:try
2: {
3:checked
4: {
5:for (; ncurdig <= Ncomputeto; ncurdig++)
6:nfactorial *= Ncurdig;
7:}
8:}
9:catch (OverflowException OE)
10: {
11:console.writeline ("Computing {0} caused an overflow exception", Ncomputeto);
12:throw;
13:}

Note that I do not have to specify the declared exception variable. Although it is optional, you can also write this:
throw OE;
Now sometimes you have to pay attention to this anomaly.

7.3.2 to create your own exception class
Although it is recommended that you use predefined exception classes, it may be convenient for you to create your own exception classes for the actual situation. Create your own exception class that allows the user of your exception class to take different measures depending on the exception class.
The exception class myimportantexception that appears in listing 7.9 follows two rules: first, it ends the class name with exception. Second, it implements all three recommended generic structures. You should also follow these rules.
Listing 7.9 implements your own exception class Myimportantexception

1:using System;
2:
3:public class Myimportantexception:exception
4: {
5:public myimportantexception ()
6:: Base () {}
7:
8:public myimportantexception (String message)
9:: Base (Message) {}
10:
11:public myimportantexception (String message, Exception inner)
: Base (Message,inner) {}
13:}
14:
15:public class Exceptiontestapp
16: {
17:public static void Testthrow ()
18: {
19:throw New Myimportantexception ("Something bad has happened.");
20:}
21st:
22:public static void Main ()
23: {
24:try
25: {
26:exceptiontestapp.testthrow ();
27:}
28:catch (Exception e)
29: {
30:console.writeline (e);
31:}
32:}
33:}

As you can see, the myimportantexception exception class does not implement any special functionality, but it is entirely based on the System.Exception class. The remainder of the program tests the new Exception class and uses a catch statement for the System.Exception class.
What's the point of creating a myimportantexception without a special implementation and just defining three constructors for it? It's an important type-you can use it in a catch statement instead of a more mundane exception class. The client code that may be causing your new exception can be used in accordance with the prescribed catch code.
When you write a class library using your own namespace, you also place the exception in that namespace. Although it does not appear in this example, you should still use the appropriate attributes to extend your exception class for extended error messages.

7.4 "to" and "no" for exception handling
As a last word of advice, here is a list of what to do and what to do with exception initiation and processing:
。 Provides meaningful text when an exception is thrown.
。 To throw an exception only if the condition is a true exception, that is, when a normal return value is not satisfied.
。 If your method or property is passed a bad argument, throw a ArgumentException exception.
。 A InvalidOperationException exception is thrown when the calling operation does not fit the current state of the object.
。 To throw the most appropriate exception.
。 To use link exceptions, they allow you to trace the exception tree.
。 Do not use exceptions for normal or expected errors.
。 Do not use exceptions for normal control of the process.
。 Do not throw NullReferenceException or IndexOutOfRangeException exceptions in the method.

7.5 Summary
This chapter begins with an introduction to overflow verification. You can use the compiler switch (the default is off) so that the entire application allows or disables overflow checksums. If you need to fine-tune the control, you can use a checksum check statement that allows you to use or not use overflow checksums to execute a piece of code, although no switches are set for the application.
An exception is thrown when an overflow occurs. How you handle exceptions depends on you. I have suggested a variety of ways, including the try, catch, and finally statements that you are most likely to use throughout your application. In many of the accompanying examples, you have learned the difference between it and the WIN32 structure exception handling (SEH).
Exception handling is for the user of the class; However, if you are responsible for creating a new class, you can throw an exception. There are a number of options: throwing an already-caught exception, triggering an existing frame exception, or creating a new exception class to the specified actual target.
Finally, you need to read the various "wants" and




Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.