Today, we are going to take a look at Switch on the Code's namesake -
the
switch
statement. More specifically, we are going to take a look
at some of the lesser known behaviors of the switch
statement in C#,
hopefully giving you some new syntactic sugar to use in the process.
You might have thought that it doesn't get much simpler in programming
than the switch statement, and you are mostly right. But there are a
couple useful things to know about the C# switch statement that fall
under the category of advanced. For instance - fall through. The C#
switch statement does not allow fall through like the C++ one does,
although it does allow a specific variation of fall through.
The fall through shown below, while valid in the C++ world, causes a
compile error in C#:
public void DoASwitch(int num)
{
switch (num)
{
case 0:
Console.WriteLine("I'm in case 0!");
case 1:
Console.WriteLine("I'm in case 1!");
break;
}
}
//Error: Control cannot fall through from one case label ('case 0:') to another
Yes, I know, this isn't an advanced feature at all - this is the lack of
an advanced feature! If you are from the C++ world, you are probably
wondering why the C# designers got rid of this sometimes very useful
feature. Well, don't worry, they didn't leave us all hanging out to dry
- the reason I showed what was not allowed is so that what is allowed
makes more sense.
In C#, we are allowed to do a very specific type of fall through -
although in some ways it is not fall through at all, it is more like
case grouping:
public void DoASwitch(int num)
{
switch (num)
{
case 0:
case 1:
case 2:
Console.WriteLine("I'm in case 0, 1 or 2!");
break;
case 3:
case 4:
case 5:
Console.WriteLine("I'm in case 3, 4 or 5!");
break;
}
}
When you group cases together like that, it is essentially like a bunch
of ORs. In this case, we are saying "for 0 or 1 or 2, do X, and for 3 or
4 or 5, do Y".
Powerful, but still not as powerful as regular fall through. But don't
worry - this next part is the cool one. So the designers of C# didn't
want implicit fall through - they felt that it lead to less readable
code and more programming mistakes. But they didn't have a problem with
the concept of fall through itself - so instead they gave C# a way to
define explicit fall through. Although really, it is actually more
powerful than fall through. Take a look at the next code block:
public enum State { One, Two, Three, Four };
public void DoASwitch(State mystate)
{
switch (mystate)
{
case State.One:
Console.WriteLine("I'm in state one!");
break;
case State.Two:
Console.WriteLine("I'm in state two!");
goto case State.Four;
case State.Three:
Console.WriteLine("I'm in state three!");
goto case State.Two;
case State.Four:
Console.WriteLine("I'm in state four!");
goto case State.One;
}
}
That's right, in C# we have the ability to
goto
a case label! This
means that we can walk all over this switch statement, and go to any
case we want at any point - we are no longer limited to falling though
the statement. For instance, say I passed in State.Three
to this
function. It would actually end up hitting every case block, and
printing out the following:I'm in state three!
I'm in state two!
I'm in state four!
I'm in state one!
Cool, eh? It doesn't quite stop there, we have a little more excitement.
You can also use this
goto
statement to go to the default case in a
switch
statement. For instance:public enum State { One, Two, Three, Four };
public static void DoASwitch(State mystate)
{
switch (mystate)
{
case State.One:
Console.WriteLine("I'm in state one!");
break;
case State.Two:
Console.WriteLine("I'm in state two!");
goto default;
case State.Three:
Console.WriteLine("I'm in state three!");
goto default;
case State.Four:
Console.WriteLine("I'm in state four!");
goto default;
default:
Console.WriteLine("I'm at the default!");
break;
}
}
Here, in all cases except for
State.One
, we go to the default
block
before leaving the statement.
One thing to watch out for when doing these explicit case jumps - it is
easy to get into an infinite loop. In fact, the compiler even allows you
to do something as silly as this:
public enum State { One, Two, Three, Four };
public static void DoASwitch(State mystate)
{
switch (mystate)
{
case State.One:
Console.WriteLine("I'm in state one!");
goto case State.One;
}
}
And I'm sure you can see as soon as you look at that goto statement that
once the program enters that block of code it is not going to leave
anytime soon.
Well, that's all for today. If you didn't know about C#'s ability to
jump between case blocks, I hope that this info leads to some prettier
code - and if you did know, I hope the article wasn't too boring.
Comments
Post a Comment