11.6 Flow control with the goto keywordYes, goto is still there in C#, although the makers of Java got rid of its functionality (still reserving the goto keyword) when they designed Java from C++. Nevertheless, do you realize that if you have been using labels in Java, and break -ing or continue -ing to such labels, you are actually performing a pseudo goto (without the goto keyword)? There are three ways to use C#'s goto :
11.6.1 Using goto in switch-case blocksgoto can be quite useful in switch - case blocks too, since 'falling-through' case blocks is no longer supported in C#. Their use should be clear from this example (see section 11.4): 1: using System; 2: 3: class TestClass{ 4: public static void Main(){ 5: int i = 1; 6: 7: switch(i){ 8: case 1 : Console.WriteLine("ONE"); 9: goto case 3 ; 10: 11: case 2 : Console.WriteLine("TWO"); 12: break; 13: 14: case 3 : Console.WriteLine("THREE"); 15: goto default; 16: 17: default : Console.WriteLine("DEFAULT"); 18: break; 19: } 20: } 21: } Output: c:\expt>test ONE THREE DEFAULT Study line 9 which shows how the goto case expression is used to force both the case 1 and case 3 blocks to be executed in the event when i ==1. 11.6.2 Using goto <label>If you use labels in Java, you can use the break and continue statements to force execution flow to continue from a particular label. C#'s break and continue keywords do not take in a label “ you use C#'s goto <label> to exit an outer loop from an inner loop prematurely. Instead of labeling the loop (which you do in Java), you label a statement outside the loop you want to break out of, and goto that statement. Study this example: 1: using System; 2: 3: class TestClass{ 4: public static void Main(){ 5: 6: for (int i=0; i<5; i++){ 7: for (int j=0; j<5; j++){ 8: Console.WriteLine(i+","+j); 9: if (j==3) 10: goto End; 11: } 12: Console.WriteLine("skipped"); 13: } 14: 15: End: // arbitrary label 16: Console.WriteLine("end"); 17: } 18: } Output: c:\expt>test 0,0 0,1 0,2 0,3 end Because of the goto End; statement on line 10, line 12 will never get to execute since the inner for loop never completes. However, the following code does not compile: 1: using System; 2: 3: class TestClass{ 4: 5: public static void Main(){ 6: 7: goto InsideLoop; 8: for (int i=0; i<5; i++){ 9: InsideLoop: 10: Console.WriteLine("looping"); 11: } 12: } 13: } Compilation warnings and error: test.cs(8,5): warning CS0162: Unreachable code detected test.cs(7,5): error CS0159: No such label 'InsideLoop' within the scope of the goto statement test.cs(9,7): warning CS0162: Unreachable code detected test.cs(9,7): warning CS0164: This label has not been referenced Line 8 is unreachable, and the compiler generates a warning (not an error though). The error thrown by the compiler is what I want to draw your attention to “ ' InsideLoop ' is not within the scope of the goto statement, since it is in a for loop. You can jump from inside a loop to outside, but not from outside to inside. [7] Even if you shift line 7 to between lines 11 and 12, you will still get the same compilation error.
If a label is specified but not used, the compiler will give a warning that the label has not been referenced. In the code example above, if line 7 is deleted but the label of line 9 is kept, the class compiles with a compilation warning, but runs fine. 11.6.3 Misusing the goto keywordAlthough you can jump around blocks of code using labels and the goto <label> statement, you should restrict its use to breaking out from inner loops . Here's an example of how the goto <label> statement can be legally abused. 1: using System; 2: 3: class TestClass{ 4: 5: public static void Main(){ 6: 7: Label1: 8: Console.WriteLine("never "); 9: goto Label2; 10: 11: Label2: 12: Console.WriteLine("ending "); 13: goto Label1; 14: } 15: } Output: c:\expt>test never ending never ending never ending never ending never ending (etc ) The output has been truncated. It carries on printing ' never ' and ' ending ' on alternate lines until you force a termination (by hitting Ctrl-C if running from the command line). |