Why is the C# switch statement designed to not allow fall-through, but still require a break?In C and C++ the switch statement allows an implicit fall-through at the end of a case. For example: switch(value) { case 0: printf(In case 0\n); case 1: printf(In case 1\n); case 2: printf(In case 2\n); break; }
The code above, when value was 0, would execute case 0, case 1, and case 2; therefore, printing: In case 0 In case 1 In case 2
This implicit fall-through behavior is often used to reduce the amount of code needed and often isnt an issue the first time that code is written. However, as code moves from the initial development phase into a maintenance phase, the code above can lead to subtle errors that are very hard to debug. These errors result from the very common mistake of the developer adding a case, yet forgetting to put a break at the end of the block. In C#, the switch statement requires that explicit flow control occur at the end of a case, either a break, goto, return, or throw. If the developer desires fall-through semantics, it can be achieved by an explicit goto at the end of a case statement. The example above could be re-written in C# as follows: switch(value) { case 0: printf(In case 0\n); goto case 1; case 1: printf(In case 1\n); goto case 2; case 2: printf(In case 2\n); break; }
Notice that this has the added benefit of allowing the cases to be re-ordered without changing the semantics of switch. Though it is possible to write the code above, the use of goto case is discouraged. Even though it makes the fall-through explicit, the developer still needs to scan all of the cases to see whether any of them contain a goto. If, however, a large number of cases map to a single behavior, it is still possible to write: switch(value) { case 0: case 1: case 2: printf(I handle case 0, 1, and 2); break; }
As a result of the C# rules requiring explicit flow-control to occur at the end of a case block (most usually a break), many people question why the behavior simply wasnt changed such that fall-through didnt occur. That is, dont make break required, simply change the semantics of switch to not have fall-through for cases. The reason this wasnt done was so that developers who were very used to C++ wouldnt have a hard time understanding what a switch statement was doing. Anson & Todd Discuss this in C# Language Forum. |