Surely the compiler knows that it's the last label of the switch
statement?
views:
203answers:
8In C# switch statements you must explicitly state to break or goto another case or goto default.
In C and C++, switch statements have fall through labels without a break. Having the user explicitly say what they want to do is important in C# to avoid bugs. A lot of users come to C# from C++ for example.
About the last case statement in particular that you're asking about. I can think of 3 good reasons.
- It's important to keep things consistent in any language.
- What if you append another case after it later on, what should be done with default?
- Why should break be the default? Why not goto? There is ambiguity here.
It's because in C++ this is what happens:
switch(a)
{
case 1:
// do stuff
case 2:
// do other stuff
}
If a
is 1, then - according to C++ rules - both "do stuff" and "do other stuff" would happen. So that C++ programmers coming to C# do not get tripped up (and to make code clearer all 'round), C# requires that you explicitly specify whether you want to break
or fall through to a different label.
Now, as for why you need the break
on the last block, that's a simple matter of consistency. It also make re factoring easier: if you move the cases around, you don't suddenly end up with errors because of a missing break
statement. Also, what happens when you want to add another label, etc, etc.
Consistency. Same reason as being able to have a comma after the last enum definition or the last assignment in an object instantiation statement with braces. And the last case might not always be the last case.
It also makes it so there are fewer special cases.
And if that's the case, then it is easier to learn, write, or read. Although that adds to the consistency thing.
Having a break after your switch's final case statement is good defensive programming. If, perhaps in the future, another case statement is added below, it removes the risk of the program's flow falling through from the case above.
When using a switch
, to break
is not the only option. You also have the option of going to another case, going to the default case, going to another label, or returning. It is also possible to have multiple cases that have a single implementation body. Since there are up to five options plus the ability to have multiple cases for one implementation, the compiler is not able to simply put in the "correct" answer.
You have to choose what you intend to do. It ensures the compiler does the right thing, makes your code clearer, and makes it more difficult to do dumb-programmer-things, like add another case after the "last one", and forget to put in a break/goto/return.
According to http://msdn.microsoft.com/en-us/library/06tc147t.aspx
You cannot "fall through" any switch section, including the last one.
Fall through can be avoided by any of the following: break, goto, or return.
Actually There is one case when you don't have to put break
Consider this code:
using System;
public class Program
{
public static void DoStuff()
{
}
public static void DoAnotherStuff()
{
}
public static void Main()
{
switch(1)
{
case 1: DoStuff(); break;
default: DoAnotherStuff();
}
}
}
Using C# 4.0 compiler it only gives you a nice CS0162: Unreachable code warning
It appears that since switch has a constant expression the compiler already knows wich path it's going to execute, then just ignores the dafault label.
The cool thing is that if you change switch(1) to switch(2) it no longer compiles because the default label lacks its break.
Edit: From the C# Reference
The requirement in C# is that the end of every switch section, including the final one, is unreachable. Although this requirement usually is met by using a jump statement, the following case also is valid, because the end of the statement list cannot be reached.
case 4:
while (true)
Console.WriteLine("Endless looping. . . .");
That explains why the default does not need a break. In fact any unreacheable label doesn't need a break nor return nor goto
According to this blog post by Eric Lippert (Case 2), it allows you to be able to arbitrarily re-order your switch sections without accidentally introducing a breaking change:
It [the compiler] requires that every switch section, including the last one, have an unreachable end point. The purpose of this rule, and of the no-fall-through rule in general, is that we want you to be able to arbitrarily re-order your switch sections without accidentally introducing a breaking change.