Switches

Switches

The Crash Course

  • Switch statements are an alternative to many if/if else/if elseelse blocks.

Instead of this:

int menuChoice = 2;
if(menuChoice == 1) 
{ 
    Console.WriteLine("You chose option #1"); 
}
else if(menuChoice == 2) 
{ 
    Console.WriteLine("You chose option #2.  I like that one too!"); 
}
else 
{ 
    Console.WriteLine("I don't know what to do with that number."); 
}

You'd do this:

int menuChoice = 2;
 
switch (menuChoice)
{
    case 1:
        Console.WriteLine("You chose option #1");
        break;
    case 2:
        Console.WriteLine("You chose option #2.  I like that one too!");
        break;
    default:
        Console.WriteLine("I don't know what to do with that number.");
        break;
}
  • Unlike C++ and Java, there's no implicit fall-through, meaning that you can't leave out the break statements and allow code to go from one case block to the next, with the exception of putting multiple case labels together (with no code at all between them).

Introduction

In the previous tutorial, we looked at basic if-statements and decision-making. Before moving on to the next real topic, we want to take a moment and discuss a construct in C# that is very similar to if statements. These statements are called switch statements. We'll take a look at when we'd want to use switch statements, how to do them, and then wrap up with a couple of extra details about switch statements.

The Basics of Switch Statements

It is pretty common to have a variable and want to do something different depending on the value of that variable. For instance, let's say we have a menu with five choices (1-5), and the user types in their choice, which we store in a variable. We want to do something different, depending on which value they chose.

We'd probably think about a sophisticated if/else-if statement using what we already know. Or rather, an ifelsle if/else if/else. Something like this:

int menuChoice = 3;
 
if (menuChoice == 1)
{
    Console.WriteLine("You chose option #1.");
}
else if (menuChoice == 2)
{
    Console.WriteLine("You chose option #2.  I like that one too!");
}
else if (menuChoice == 3)
{
    Console.WriteLine("I can't believe you chose option #3.");
}
else if (menuChoice == 4)
{
    Console.WriteLine("You can do better than 4....");
}
else if (menuChoice == 5)
{
    Console.WriteLine("5?  Really?  That's what you went with?");
}
else
{
    Console.WriteLine("Hey! That wasn't even an option!");
}

That gets the job done, but there's another way, using a concept called a switch statement. To make a switch statement, we'll use the switch keyword and a case keyword for each of the various "cases" or options that we have. (We'll also use the break and default keywords, but we'll talk about those more in a second.) The if statement we had above would look like this as a switch statement:

int menuChoice = 3;
 
switch (menuChoice)
{
    case 1:
        Console.WriteLine("You chose option #1");
        break;
    case 2:
        Console.WriteLine("You chose option #2.  I like that one too!");
        break;
    case 3:
        Console.WriteLine("I can't believe you chose option #3.");
        break;
    case 4:
        Console.WriteLine("You can do better than 4....");
        break;
    case 5:
        Console.WriteLine("5?  Really?  That's what you went with?");
        break;
    default:
        Console.WriteLine("Hey! That wasn't even an option!");
        break;
}

As you can see, we start out with the switch statement, and in parentheses, we put the variable we are going to "switch" based on. (In this case, think of the "switch" word like a railroad switch, where the switch determines where things go.)

Then, we have a sequence of case statements, or case labels, which indicate that if the variable matches the value of the case statement, the contained block of code is where the flow of execution will go.

It is important to note that the flow of execution will go into exactly one of the case labels, so you will never end up in a situation where more than one case block gets executed.

At the end of each case block, we're required to put the break keyword, which sends the flow of execution back outside of the entire switch statement and onward into the rest of the code.

Notice, too, that we can have a default label, which indicates that if none of the other case labels are a match, then the flow of execution should go here instead. Thedefault label doesn't need to be the last one, but typically, that's where people put it, and it is good practice to do so. The default block works as a sort of catch-all for anything other than the specific situations of the other case labels. Note, too, that this is like the final else block in our original giant if statement.

While all switches could be done with if statements, not all if statements can be represented with a switch.

No Implicit Fall-Through

If you are coming from the C++ or Java world into the C# world, you may be aware of a little trick that you can do, where one case block "falls through" to the next block if you leave off the break statement.

For instance, you can do this in C++ and Java:

// This doesn't work in C#
switch (menuChoice)
{
    case 1:
        Console.WriteLine("You chose 1.");
    case 2:
        Console.WriteLine("You chose 2.  Or maybe you chose 1.");
        break;
}

Because there's no break, in case 1, the code there would be executed and then continue on down into the case 2 block until you hit a break statement. This isn't allowed in C#. Every case block needs a break statement.

The reason for requiring this is that people accidentally ended up doing this far more often than they intentionally used it. They leave off the break statement by accident, resulting in a bug that is usually somewhat tricky to resolve. To prevent this, C# won't even allow you to leave off the break statement and fall through.

However, there is one situation where you can do this. That situation is if you have multiple case blocks with no code in between it:

// This does work in C#
switch (menuChoice)
{
    case 1:
    case 2:
        Console.WriteLine("You chose option 1 or 2.");
        break;

This allows you to do the same thing, regardless of whether the value is 1 or 2. And in this case, while case 1 doesn't have a break statement, it also doesn't need it because we're simply saying "cases 1 and 2 are the same thing."

This could be thought of as basically something like "if [something] or [something else], then do [something cool]". You can write the same thing with an if statement as well.

Switch Expressions

There is a second flavor of switch that doesn't use statements. Rather, it is an expression, and can be used as a part of a bigger expression. These switch expressions are great for mapping one set of values to another. This is easier to show than describe, so let's look at an example:

Console.Write("Type a number word like 'four': ");
string word = Console.ReadLine();
int number;
number = word switch
{
    "zero" => 0,
    "one" => 1,
    "two" => 2,
    "three" => 3,
    "four" => 4,
    "five" => 5,
    "ten" => 10,
    "one hundred" => 100,
    _ => -1
};
 
if (number == -1)
{
    Console.WriteLine("I did not understand that.");
}
else
{
    Console.WriteLine("I recognized that. It was the number " + number + "!");
}

The switch expression allows us to check for certain values and produce another result. The thing to compare against comes before the => while the end result in that case comes after. The _ is a catch-all and handles any other non-handled case, just like default does in a switch statement.

We'll see more uses of this later on.

Only Scratching the Surface

We're really only scratching the surface of switches in this tutorial. Switches are one of several ways to use pattern matching, which is its own whole topic for another day.

What's Next?

With the basics of decision-making behind us, you're in great shape and making great progress. (Think of all the cool things you can do with this technology!) Up next: going in circles…. Looping!