Compared to Java and C/C++, the
switch statement as implemented in the C# language (section 15.7.2 of ECMA standard 334) offers more flexibility. Whereas other languages limit its use to integer types, in C# the expression passed into the statement can be any of
string, or an
enum-type, or even any other type that is implicitly convertible to one and only one of the above. The ability to select blocks of code based on strings is something that I always missed in Java (having used it extensibly in PHP) and I was glad to find out C# allows it too.
Another difference is that implicit fall-through is not allowed: the use of the
break statement in the selective blocks is compulsory and forgetting it would generate a compile error. This was done to eliminate that nasty source of bugs in Java, C, PHP, et al. whereby leaving out
break in the code would produce all sorts of strange results as the code for the following blocks would be executed sequentially despite the
case value not matching the
switch expression. The approach followed in C# was that
break is required. Full stop. But sometimes fall-through is actually used consciously by programmers to achieve specific results: so the C# designers have taken the stance that you can fall through
cases, but you need to declare it explicitly. Now, at this point I would have liked something like a
fallthrough statement, instead we get a
goto are rather controversial, as the use of unconditional jumping is usually frowned upon in today’s programming. You should always use the structured branching features of the language of your choice, instead of happily moving from label to label within your code. In C# and within a
goto allows you to specify the case you want to go to (
goto case keyword followed by value) or the default block (
goto default keyword).
Imho, offering should a powerful statement as
goto to implement explicit fall-through can easily lead the lazy programmer (like myself) to use it in a way that exploits its flexibility against good code design practices. Yet, I’m grateful for making
break necessary and issuing a compile error when it’s not there: that does safe debugging time. And at the same time, it’s good to know we can still fall-through when we want to, even if with the risk of abusing it.