Teach Yourself the C# Language in 21 Days phần 5 pdf

81 418 1
Teach Yourself the C# Language in 21 Days phần 5 pdf

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

Handling Problems in Your Programs: Exceptions and Errors 299 9 provide cleaner results than pop-up boxes, terminated programs, and cryptic messages. To do this, you use the try and catch keywords. Using try and catch The try and catch keywords are the key to exception handling. The try command enables you to put a wrapper around a block of code that helps you route any problems (excep- tions) that might occur. The catch keyword enables you to catch the exceptions that the try command routes. By using a catch, you get the chance to execute code and control what happens rather than letting the program terminate. Listing 9.2 illustrates a basic use of the try and catch com- mands. LISTING 9.2 TryIt.cs—Using try-catch 1: // TryIt.cs 2: // A program that throws an exception 3: //============================================= 4: using System; 5: 6: class TryIt 7: { 8: public static void Main() 9: { 10: int [] myArray = new int[5]; 11: 12: try 13: { 14: for ( int ctr = 0; ctr < 10; ctr++ ) // Array only has 5 ele- ➥ments! 15: { 16: myArray[ctr] = ctr; 17: } 18: } 19: 20: catch 21: { 22: Console.WriteLine(“The exception was caught!”); 23: } 24: 25: Console.WriteLine(“At end of class”); 25: } 27: } The exception was caught! At end of class OUTPUT This listing is similar to Listing 9.1, but it has basic exception handling added using try and catch. In this version of the listing, the main code is wrapped in a try statement, which starts in Line 12. It uses braces (Lines 13 and 18) to enclose a block of code that is to be watched for exceptions. In this listing, the code that manipulates the array is enclosed in the try statement. Following the try statement is a catch statement that starts in Line 20 and includes the statements between its braces (Lines 21 and 23). If an exception is found while executing the code within the try statement, control immediately goes to the catch statement. Instead of the results you saw in Listing 9.1, in which a cryptic message was displayed and the program ended, in this listing the code within the catch statement’s block exe- cutes. The program then continues to operate. In Listing 9.2, the catch statement prints a message and the program flow then continues. Line 25, which contains a call to the WriteLine method, is still executed. Catching Exception Information In Listing 9.2, the catch statement catches any exception that might occur within the try statement’s code. In addition to generically catching thrown exceptions, you can deter- mine which exception was thrown by including a parameter on your catch. The format of the catch is as follows: catch( System.Exception e ) {} The catch statement can receive the exception as a parameter. In this example, the excep- tion is a variable named e. You could call this something more descriptive, but for this example, the name e works. You can see that e is of type System.Exception, a fully qualified name meaning that the Exception type is defined in the System namespace. If you include the System statement with a using statement, you can shorten the catch call to this: catch(Exception e) {} The Exception type variable e contains descriptive information on the specific exception that was caused. Listing 9.3 is a modified version of Listing 9.2, containing a catch state- ment that receives any exceptions as a parameter. The changed lines are in boldface. LISTING 9.3 TryIt2.cs—Catching Exception Information 1: // TryIt2.cs 2: // A program that throws an exception 3: //============================================= 4: using System; 300 Day 9 ANALYSIS Handling Problems in Your Programs: Exceptions and Errors 301 9 5: 6: class TryIt2 7: { 8: public static void Main() 9: { 10: int [] myArray = new int[5]; 11: 12: try 13: { 14: for ( int ctr = 0; ctr < 10; ctr++ ) // Array only has 5 ele- ➥ments! 15: { 16: myArray[ctr] = ctr; 17: } 18: } 19: 20: catch( Exception e) 21: { 22: Console.WriteLine(“The following exception was caught:\n{0}”, e); 23: } 24: 25: Console.WriteLine(“At end of class”); 26: } 27: } The following exception was caught: System.IndexOutOfRangeException: Index was outside the bounds of the array. at TryIt2.Main() At end of class Listing 9.3 doesn’t do much with the exception; however, you can gain a lot of information from what it does. In Line 22, e is printed using the WriteLine method. This displays information on the exception. Looking at the output, you see that the value of e indicates that the exception thrown was an IndexOutOfRangeException and occurred in the Main() method of the MyAppClass—which is your program’s class. This listing catches all exceptions that occur within the try statement. The error printed is based on the type of exception executed. You can actually add code to your program to work with specific errors. LISTING 9.3 continued ANALYSIS OUTPUT Using Multiple catches for a Single try The catch statement in Listing 9.2 is rather general. It can catch any exception that might have occurred in the code within the try statement code. You can include a catch state- ment that is more specific—in fact, you can write a catch statement for a specific excep- tion. Listing 9.4 includes a catch statement that captures the exception you are already familiar with—IndexOutOfRangeException. LISTING 9.4 CatchIndex.cs—Catching a Specific Exception 1: // CatchIndex.cs 2: // A program that throws an exception 3: //============================================= 4: using System; 5: 6: class CatchIndex 7: { 8: public static void Main() 9: { 10: int [] myArray = new int[5]; 11: 12: try 13: { 14: for ( int ctr = 0; ctr < 10; ctr++ ) // Array only has 5 ele- ➥ments! 15: { 16: myArray[ctr] = ctr; 17: } 18: } 19: 20: catch (IndexOutOfRangeException e) 21: { 22: Console.WriteLine( ➥”You were very goofy trying to use a bad array index!!”, e); 23: } 24: 25: catch (Exception e) 26: { 27: Console.WriteLine(“Exception caught: {0}”, e); 28: } 302 Day 9 Once again, the exception was caught and the program continued to exe- cute. Using a catch statement, you can prevent weird error messages from being automatically displayed. Additionally, the program doesn’t terminate at the moment the exception occurs. Note Handling Problems in Your Programs: Exceptions and Errors 303 9 29: 30: Console.WriteLine(“\nDone with the catch statements. Done with pro- ➥gram.”); 31: } 32: } You were very goofy trying to use a bad array index!! Done with the catch statements. Done with program. This listing uses the same array and the same try command that you used in the previous listings, but Lines 20–23 feature something new. Instead of having a parameter for a general exception, the catch statement in Line 20 has a parameter for an IndexOutOfRangeException type. Like the general Exception type, this is in the System namespace. Just as its name implies, this exception type is specifically for indexes that go out of range. This catch statement captures only this type of exception, though. To be prepared for other exceptions that might occur, a second catch statement is included in Lines 25–28. This catch includes the general Exception type parameter, so it will catch any other exceptions that might occur. Replace Line 16 of Listing 9.4 with the following: 16: myArray[ctr] = 100/ctr; // division by zero When you recompile and run the program, you will get the following output: Exception caught: System.DivideByZeroException: Attempted to divide by zero. at CatchIndex2.Main() Done with the catch statements. Done with program. The new Line 16 causes a different error. The first time through the for loop in Line 14, ctr is equal to 0. Line 16 ends up dividing 100 by 0 (ctr). Division by 0 is not legal because it creates an infinite number, and thus an exception is thrown. This is not an index out of range, so the catch statement in Line 20 is ignored because it doesn’t match the IndexOutOfRangeException type. The catch in Line 25 can work with any exception and thus is executed. Line 27 prints the statement “Exception Caught”, followed by the excep- tion description obtained with the variable e. As you can see by the output, the exception thrown is a DivideByZeroException. Understanding the Order of Handling Exceptions In Listing 9.4, the order of the two catch statements is very important. You always include the more specific exceptions first and the most general exception last. Starting with the original Listing 9.4, if you change the order of the two catch statements: LISTING 9.4 continued OUTPUT ANALYSIS catch (Exception e) { Console.WriteLine(“Exception caught: {0}”, e); } catch (IndexOutOfRangeException e) { Console.WriteLine( ➥”You were very goofy trying to use a bad array index!!”, e); } When you recompile, you get an error. Because the general catch(Exception e) catches all the exceptions, no other catch statements are executed. Adding Finality with finally Sometimes you will want to execute a block of code regardless of whether the code in a try statement succeeds or fails. C# provides the finally keyword to take care of this (see Listing 9.5). The code in a finally block always executes. LISTING 9.5 Final.cs—Using the finally Keyword 1: // Final.cs 2: // A program that throws an exception 3: //============================================= 4: using System; 5: 6: class Final 7: { 8: public static void Main() 9: { 10: int [] myArray = new int[5]; 11: 12: try 13: { 14: for ( int ctr = 0; ctr < 10; ctr++ ) // Array only has 5 ele- ➥ments! 15: { 16: myArray[ctr] = ctr; 17: } 18: } 19: 20: // catch 21: // { 22: // Console.WriteLine(“Exception caught”); 23: // } 24: 25: finally 304 Day 9 Handling Problems in Your Programs: Exceptions and Errors 305 9 26: { 27: Console.WriteLine(“Done with exception handling”); 28: } 29: 30: Console.WriteLine(“End of Program”); 31: } 32: } Unhandled Exception: System.IndexOutOfRangeException: Index was outside ➥ the bounds of the array. .IndexOutOfRangeException was thrown. at Final.Main() Done with exception handling Listing 9.5 is the same listing you saw before. The key change to this listing is in Lines 25–28: A finally clause has been added. In this listing, the finally clause prints a message. It is important to note that even though the exception was not caught by a catch clause (Lines 20–23 are commented out), the finally still executed before the program terminated. The WriteLine command in Line 30, however, doesn’t execute. Remove the comments from Lines 20–23 and rerun the program. This time, you receive the following output: Exception caught. Done with exception handling End of Program The use of a catch does not preclude the finally code from happening. Now change Line 14 to the following: 14: for ( int ctr = 0; ctr < 5; ctr++ ) Then recompile and run the program; you will get the following output: Done with exception handling End of Program Notice that this change to Line 14 removed the problem that was causing the exception to occur. This means that the listing ran without problems. As you can see from the out- put, the finally block was still executed. The finally block will be executed regardless of what else happens. Now is a good time to show a more robust example that uses exception handling. Listing 9.6 illustrates a more practical program. LISTING 9.5 continued OUTPUT ANALYSIS OUTPUT OUTPUT LISTING 9.6 ListFile.cs—Using Exception Handling 1: // ListFile.cs - program to print a listing to the console 2: // 3: 4: using System; 5: using System.IO; 6: 7: class ListFile 8: { 9: public static void Main(string[] args) 10: { 11: try 12: { 13: 14: int ctr=0; 15: if (args.Length <= 0 ) 16: { 17: Console.WriteLine(“Format: ListFile filename”); 18: return; 19: } 20: else 21: { 22: FileStream fstr = new FileStream(args[0], FileMode.Open); 23: try 24: { 25: StreamReader sReader = new StreamReader(fstr); 26: string line; 27: while ((line = sReader.ReadLine()) != null) 28: { 29: ctr++; 30: Console.WriteLine(“{0}: {1}”, ctr, line); 31: } 32: } 33: catch( Exception e ) 34: { 35: Console.WriteLine(“Exception during read/write: {0}\n”, e); 36: } 37: finally 38: { 39: fstr.Close(); 40: } 41: } 42: } 43: 44: catch (System.IO.FileNotFoundException) 45: { 46: Console.WriteLine (“ListFile could not find the file {0}”, args[0]); 47: } 48: catch (Exception e) 306 Day 9 Handling Problems in Your Programs: Exceptions and Errors 307 9 49: { 50: Console.WriteLine(“Exception: {0}\n\n”, e); 51: } 52: } 53: } Format: ListFile filename If you run this program, you get the output displayed. You need to include a file- name as a parameter to the program. If you run this program with ListFile.cs as the parameter, the output will be the listing with line numbers: 1: // ListFile.cs - program to print a listing to the console 2: // 3: 4: using System; 5: using System.IO; 6: 7: class ListFile 8: { 9: public static void Main(string[] args) 10: { 11: try 12: { 13: 14: int ctr=0; 15: if (args.Length <= 0 ) 16: { 17: Console.WriteLine(“Format: ListFile filename”); 18: return; 19: } 20: else 21: { 22: FileStream fstr = new FileStream(args[0], FileMode.Open); 23: try 24: { 25: StreamReader sReader = new StreamReader(fstr); 26: string line; 27: while ((line = sReader.ReadLine()) != null) 28: { 29: ctr++; 30: Console.WriteLine(“{0}: {1}”, ctr, line); 31: } 32: } 33: catch( Exception e ) 34: { 35: Console.WriteLine(“Exception during read/write: ➥{0}\n”, e); LISTING 9.6 continued OUTPUT ANALYSIS OUTPUT [...]... 214 74836 45 214 7483646 assigned from 214 7483646 214 7483647 assigned from 214 7483647 -214 7483648 assigned from 214 7483648 -214 7483647 assigned from 214 7483649 -214 7483646 assigned from 214 7483 650 -214 74836 45 assigned from 214 7483 651 -214 7483644 assigned from 214 7483 652 -214 7483643 assigned from 214 7483 653 9 320 Day 9 -214 7483642 assigned from 214 7483 654 -214 7483641 assigned from 214 7483 655 -214 7483640... reason to continue processing the file after the null value is encountered If the characters read and placed into line are not equal to null, the while statement processes its block commands In this case, the line counter, ctr, is incremented and the line of text is printed The printing includes the line number, a colon, and the text from the file that is in the line variable This processing continues until... follows: csc /define:DEBUG Reading.cs Here, DEBUG is any value that you want defined in the listing and Reading.cs is your listing name If you compile Listing 9.10 using the /define switch, DEBUG is again defined without the need to change your code Leaving the /define off the command line stops the debugging information from being displayed The end result is that you can turn the debugging information... associated with the file the reader entered, the ReadLine method returns the next line of characters from the user’s file This line of characters is then assigned to the line string variable After reading this line of characters and placing it into the line variable, the value is compared to null If the string returned was null, it was either the end of the file or a bad read Either way, there is no reason... but so is the IO namespace within System The IO namespace contains routines for sending and receiving information (input/output) In Line 7, you see the start of the main application class, ListFile This class has a Main routine, where program execution starts In Line 9, the Main method receives a string array named args as a parameter The values within args are obtained from the command-line arguments... on the line number ANALYSIS You can see in the compiler output that the warnings are numbered based on the #line values, not on the actual line numbers Obviously, there are not 100 lines in this listing These directive line numbers are used in the #warning directives, as well as warnings and errors produced by the compiler You also can return line numbers within a section of the listing back to their... value is the length of the line being printed This length information can be used for debugging purposes Again, when the listing is released, by undefining DEBUG, this information won’t be included As you can see, defining a value is relatively easy One of the values of using directives was to prevent the need to change code; yet, to change whether DEBUG is defined, you must change Line 5 in Listing 9.10... width included If the line is not too long, the line prints normally By undefining BOOKCHECK, I can have this logic removed Changing Line Numbers Another directive that is provided is the #line directive This directive enables you to change the number of the lines in your code The impact of this can be seen when you print error messages Listing 9.12 presents a listing using the #line directive LISTING... Lines.cs(102,16): Lines.cs(106,16): Lines.cs(203,16): Lines.cs(303,16): Lines.cs(204,11): ➥never used Lines.cs(304,11): ➥never used warning warning warning warning warning CS1030: CS1030: CS1030: CS1030: CS0168: #warning: In Main ’ #warning: ‘Done with main’ #warning: In Method 1 ’ #warning: In Method 2 ’ The variable ‘x’ is declared but warning CS0168: The variable ‘y’ is declared but The following is the output... alternative to this is to define a value when compiling Handling Problems in Your Programs: Exceptions and Errors 327 Defining Values on the Command Line Remove Line 5 from Listing 9.10 and recompile You will see that the extra debugging information is left out To define DEBUG without adding Line 5 back into the listing, you can use the /define flag on the compile option The format of this compile option . case, the line counter, ctr, is incremented and the line of text is printed. The printing includes the line number, a colon, and the text from the file that is in the line variable. This processing. Final.Main() Done with exception handling Listing 9 .5 is the same listing you saw before. The key change to this listing is in Lines 25 28: A finally clause has been added. In this listing, the. exe- cutes. The program then continues to operate. In Listing 9.2, the catch statement prints a message and the program flow then continues. Line 25, which contains a call to the WriteLine method, is

Ngày đăng: 13/08/2014, 08:20

Từ khóa liên quan

Tài liệu cùng người dùng

  • Đang cập nhật ...

Tài liệu liên quan