C # sharp experience
Nanjing University of Posts and Telecommunications
Li Jianzhong (
Lijianzhong@263.net.cn
)
Chapter 16
Abnormal processing
Abnormal processing
??????? Structured Abnormally Handling is a necessary link in the modern distributed environment, .NET General language is based on the underlying structure to abnormally handle it with solid support. In C #, the exception object is designed to encapsulate a class of various exception information (System.exception and its inheritance subclasses, and the interface is similar, it is recommended to name "Exception", but this is not necessary), "Try-catch-finally" statement and exception objects are designed for C # component to provide a package from exception detection, exception capture and processing. Let's take a typical example:
Using system;
Class test
{
???? public static void main ()
???? {
???????? INT x = 0;
???????? Try
???????? {
???????????? INT Y = 10 / x; // divided into zero
???????????? console.writeline ("try end!");
????????}
???????? caratch (DivideByzeroException E)
???????? {
???????????? console.writeline ("DivideByzeroException ->" E);
????????}
???????? caratch (Exception E)
???????? {
???????????? console.writeline ("General Exception ->" E);
????????}
????}???
}
The example will produce the following output:
DivideByzeroException -> System.diVideByzeroException: Attempted to Divide by Zero.
??? at Test.main ()
We deliberately divide zero operation in the TRY sentence to generate "divided zero", in the first CATCH statement, we capture "divided zero" - DivideByzeroException, which is the type specified within Catch. As can be seen from the results, our second CATCH statement does not capture any other exceptions. This example is short, but it reveals the basic model of abnormal processing.
??????? First, we will possibly an abnormal statement in the TRY sentence block, the exception in such code may be detected and passed to the CATCH statement. The catch statement can be used with parameters or without parameters. The parameter type of the Catch statement can only be system.exception and its inheritance. The CATCH statement with parameters will capture the exception of the parameter specified type, which is not processed for other exceptions. The Catch statement without parameters is equivalent to an exception of the parameter system.exception type (ie, all exceptions), but unusual variables (as e) in the example above cannot be obtained. A TRY selection can match multiple Catch statements to capture different exception types. Here, you must pay attention to the order of multiple CATCH statements. The parameter type in the later CATCH statement cannot be a subclass of the previous type, and cannot be the same as the previous parameter type, and there is no parameter equivalent to the System.Exception type. This rules are naturally naturally in the sense of exception handling of a particular type - if the aexception type is the base class of the bexception type, then if the bexception type is exception, Catch (AException E) can capture, which will be captured below The abnormality of the bexception type will not be able to lose its meaning. The C # compiler will have an error in this situation. ??????? So how is the exception type of the parameter type of our catch statement does not match the TRY sentence detected? When this occurs, the exception will be thrown in the method of the statement. If the method is called without the corresponding detection and capture mechanism, the exception continues to be thrown until it is captured, or is thrown to the application's entry point main function to cause the program anomaly interrupt execution. This anomaly-thrown mechanism also applies to an exception that appears outside the TRY sentence - detects but not captured and no detection effect!
??????? Another point to note is that once the program has an exception, then the code behind it will not be executed! Console.Writeline in the above example ("Try End!") Is not executed because of the previous code. This also determines that our code can only be detected an exception, and you can only capture an exception!
But if we need to logically, we must do some tasks urgent code (typically closed files, network ports, etc.)? C # provides a Finally statement to solve this situation. Finally statements cannot be used separately, it and try, Catch have two matching situations. Try, Catch, Finally Three Matching Try-Catch-Finally Statements. Look at the example below:
Using system;
Public Class Test
{
???? public static void main ()
???? {
???????? Try
???????? {
???????????? console.writeline ("try ...");
???????????? throw new nullreferenceException (); // throw an exception
????????}
???????? caratch (NullreferenceException E)
???????? {
???????????? console.writeline ("NullreferenceException: {0}", E);
????????}
???????? caratch (Exception E)
???????? {
???????????? console.writeline ("exception: {0}", e);
????????}
???????? finally ???????? {
???????????? console.writeline ("Finally ...");
????????}
????}
}
Program output:
Try ...
NullReferenceException: System.NullReferenceException: Object Reference NOT set to an instance of an object.
??? at Test.main ()
Finally ...
We see that even though throwing an exception, the finally statement is also executed. The TRY statement can also be equipped with a Finally statement to make a try-finally statement. After the try-finally statement detected an abnormality, it simply throws and did not capture. However, after this exception is processed (Catch statement capture of the method being called, or reaches the MAIN function entry point is executed), the finally statement statement is still executed. Of course, the Finally statement can only have one, this is not self-motivated.
??????? We used the throw statement in the code to throw an exception. What is going on? In our code design, we often have a specific exception in our own conditions, or abnormal conditions. At this time, the throw statement is useful, let's look at the example below:
Using system;
Public class myException: ApplicationException
{
???? public myexception (String Message): Base (Message)
???? {
????}
???? public myexception (String Message, Exception Inner): Base (Message, Inner)
???? {
????}???
}
Public Class Myclass
{
???? public static void exmethod ()
???? {
???????? throw new myexception ("exception in exmethod");
????}
???? public static void mymethod ()
???? {
???????? Try
???????? {
???????????? exmethod ();
????????}
???????? caratch (Exception E)
???????? {
???????????? throw new myexception ("Exception in Mymethod", E);
????????}
????}
}
Public Class Test
{
???? public static void main ()
???? {
???????? Try
???????? {
???????????? myclass.mymethod ();
????????}
???????? caratch (Exception E)
???????? {
???????????? console.writeLine (e);
???????????? console.writeline ();
???????????? console.writeline (E.GetBaseException ());
????????}
????}
}
Program output:
MyException: Exception in mymethod ---> MyException: Exception in Exmethod
??? at myclass.exmethod ()
??? at myclass.mymethod ()
??? --- End of inner exception stack trace --- ??? at myclass.mymethod ()
??? at Test.main ()
MyException: Exception In Exmethod
??? at myclass.exmethod ()
??? at myclass.mymethod ()
In the above example, we designed our own anomaly MyException, and simply applying this anomaly in its own class design. It shows its processing in the test program, and abnormal tracking in the calls of multiple methods. Where E.GetBaseException () is a getBaseException () method that calls System.exception, obtaining the exception that causes exception E, if not, return E himself. Many methods and properties of System.Exception provide us with a good description and tracking service for exceptions. It is a good starting point for our application exception, exception, and understanding exception.
Checked
Unchecked
??????? For the "overflow exception" -System.OverflowException generated when the integer type is involved in arithmetic operation and type conversion, it is not a real "exception" in some algorithms, and this overflow is often The program is used. C # controls the need for this special situation by introducing CHECKED and UNCHECKED keywords. They can be added before a statement block (such as Checked {...}), or an arithmetic expression (such as unchecked (x y)). Among them, the statement or expression of the Checked flag is plus, if an arithmetic overflow occurs, throw an exception of the System.OverFlowException type. When an arithmetic overflow of the Unchemked flag is not thrown. Here is an example:
Using system;
Class test
{
???? static void main ()
???? {
???????? INT NUM1 = 100000, Num2 = 100000, result = 0;
???????? checked
???????? {
???????????? Try
???????????? {
???????????????? result = Num1 * Num2;
????????????}
???????????? caratch (System.OverflowException E)
???????????? {
???????????????? console.writeLine (e);
????????????}
???????????? finally
???????????? {
???????????????? console.writeline (result);
????????????}
????????}
???????? unchecked
???????? {
???????????? Try
???????????? {
???????????????? result = Num1 * Num2;
????????????}
???????????? caratch (System.OverflowException E)
???????????? {
???????????????? console.writeLine (e);
????????????}
???????????? finally
???????????? {
???????????????? console.writeline (result);
????????????}
????????}
????}
}
Program output:
System.OverflowException: Arithmetic Operation Resulted in an overflow.???t test.main ()
0
1410065408
??????? You can see the same arithmetic operation, throw overflow exceptions with Checked, and unchecked just discard the overflow bit to get the decimal integer value of the remaining 32-bit. It is worth pointing out that you can use the "/ check" compiler option to specify the code of the entire file to check the semantics, if not specified, the default is unchecked. If you specify the Checked or Unchecked flag in the program code, there is a check -d compiler option, and in addition to the logo's unchecked code, there are Checked semantics.