446 lines
13 KiB
Markdown
446 lines
13 KiB
Markdown
|
# Introduction
|
|||
|
|
|||
|
The C# programming language is similar to any human written or spoken language.
|
|||
|
They each support different ways of expressing the same idea. In spoken
|
|||
|
languages, some words and phrases are more descriptive, accurate, or succinct
|
|||
|
than others. In the C# programming language, there is more than one way to
|
|||
|
create branching logic. For example, selections that use `if` statements and
|
|||
|
selections that use `switch` statements. Depending on the context of your
|
|||
|
application, one type of selection statement might be more expressive and
|
|||
|
succinct than the other.
|
|||
|
|
|||
|
Suppose working on applications that make extensive use of selections
|
|||
|
statements. In some cases, `if-elseif-else` constructs are used to produce
|
|||
|
succinct and expressive code that is easy to read and maintain. In other cases,
|
|||
|
the `if-elseif-else` constructs produce the required result, but are difficult
|
|||
|
to read and maintain. You have been tasked with reviewing the code and
|
|||
|
determining when it is suitable to use a `switch` statement rather than an `if`
|
|||
|
statement.
|
|||
|
|
|||
|
In this module, you'll investigate the use of a `switch` statement to implement
|
|||
|
branching logic as an alternative to an `if` statement. You'll also work on
|
|||
|
converting an `if-elseif-else` construct to a `switch-case` construct. During
|
|||
|
this process, you'll learn to recognize the benefits of choosing one type of
|
|||
|
selection statement over the other.
|
|||
|
|
|||
|
By the end of this module, you'll be able to implement `switch` statements in
|
|||
|
your application, judge when to use a `switch` statement over an
|
|||
|
`if-elseif-else` construct, and convert `if-elseif-else` constructs to `switch`
|
|||
|
statements.
|
|||
|
|
|||
|
### Learning objectives
|
|||
|
|
|||
|
In this module, you will:
|
|||
|
|
|||
|
- Use the `switch-case` construct to match a variable or expression against
|
|||
|
several possible outcomes.
|
|||
|
- Convert code that uses an `if-elseif-else` construct into a `switch-case`
|
|||
|
construct.
|
|||
|
|
|||
|
---
|
|||
|
|
|||
|
## Exercise
|
|||
|
|
|||
|
### Implement a switch statement
|
|||
|
|
|||
|
A `switch` statement is a C# selection statement that provides an alternative
|
|||
|
to an `if-elseif-else` branching construct. The `switch` statement provides
|
|||
|
advantages over an `if-elseif-else` construct when evaluating a single value
|
|||
|
against a list of known matching values.
|
|||
|
|
|||
|
Consider the following scenario:
|
|||
|
|
|||
|
- You're working on an application related to food nutrition. A section of the
|
|||
|
code deals with fruits.
|
|||
|
- Your code includes a variable named `fruit` that's used to hold the name of
|
|||
|
different types of fruit.
|
|||
|
- You have a list of the 20 fruits that your application is focused on.
|
|||
|
- You want to branch your code based on the value assigned to `fruit`.
|
|||
|
|
|||
|
In this scenario, you can use a `switch` statement to create a separate branch
|
|||
|
for each type of fruit.
|
|||
|
|
|||
|
### How does a switch statement work?
|
|||
|
|
|||
|
The `switch` statement chooses one section of code to execute from a list of
|
|||
|
possible switch sections. The selected switch section is chosen based on a
|
|||
|
pattern match with the statement's match expression.
|
|||
|
|
|||
|
Consider the following code sample that shows the basic structure of `switch`
|
|||
|
statement:
|
|||
|
|
|||
|
```cs
|
|||
|
switch (fruit) {
|
|||
|
case "apple":
|
|||
|
Console.WriteLine($"App will display information for apple.");
|
|||
|
break;
|
|||
|
case "banana":
|
|||
|
Console.WriteLine($"App will display information for banana.");
|
|||
|
break;
|
|||
|
case "cherry":
|
|||
|
Console.WriteLine($"App will display information for cherry.");
|
|||
|
break;
|
|||
|
}
|
|||
|
```
|
|||
|
|
|||
|
The match expression (which may also be referred to as the switch expression)
|
|||
|
is the value following the `switch` keyword, in this case (`fruit`). Each
|
|||
|
*switch* section is defined by a *case pattern*. Case patterns are constructed
|
|||
|
using the keyword `case` followed by a value. The first case pattern in this
|
|||
|
example is: `case "apple":`. Case patterns are Boolean expressions that
|
|||
|
evaluate to either `true` or `false`. Each switch section includes a small
|
|||
|
number of code lines that will be executed if the case pattern is a match for
|
|||
|
the match expression. In this example, if `fruit` is assigned a value of
|
|||
|
"apple", the first case pattern will evaluate as `true` and that switch section
|
|||
|
will be executed.
|
|||
|
|
|||
|
A switch statement must include at least one switch section, but will normally
|
|||
|
contain three or more switch sections.
|
|||
|
|
|||
|
The switch is best used when:
|
|||
|
|
|||
|
- You have a single value (variable or expression) that you want to match
|
|||
|
against many possible values.
|
|||
|
- For any given match, you need to execute a couple of lines of code at most.
|
|||
|
|
|||
|
> Note
|
|||
|
> This first example of a `switch` statement is purposefully simple and your
|
|||
|
examination of the syntax was brief. You will be examining additional features
|
|||
|
of the `switch` statement when you work through some more advanced scenarios
|
|||
|
in the sections below.
|
|||
|
|
|||
|
It's time to prepare your coding environment and begin developing your own
|
|||
|
`switch` statements.
|
|||
|
|
|||
|
#### Prepare your coding environment
|
|||
|
|
|||
|
At the Terminal command prompt, to create a new console application in a
|
|||
|
specified folder, type dotnet new console -o ./path_to/TestProject and then
|
|||
|
press Enter.
|
|||
|
|
|||
|
This .NET CLI command uses a .NET program template to create a new C# console
|
|||
|
application project in the specified folder location.
|
|||
|
|
|||
|
#### Create and test a switch statement
|
|||
|
|
|||
|
Type the following code into the editor:
|
|||
|
|
|||
|
```cs
|
|||
|
int employeeLevel = 200;
|
|||
|
string employeeName = "John Smith";
|
|||
|
|
|||
|
string title = "";
|
|||
|
|
|||
|
switch (employeeLevel) {
|
|||
|
case 100:
|
|||
|
title = "Junior Associate";
|
|||
|
break;
|
|||
|
case 200:
|
|||
|
title = "Senior Associate";
|
|||
|
break;
|
|||
|
case 300:
|
|||
|
title = "Manager";
|
|||
|
break;
|
|||
|
case 400:
|
|||
|
title = "Senior Manager";
|
|||
|
break;
|
|||
|
default:
|
|||
|
title = "Associate";
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
Console.WriteLine($"{employeeName}, {title}");
|
|||
|
```
|
|||
|
|
|||
|
The Program.cs file must be saved before building or running the code.
|
|||
|
|
|||
|
At the Terminal command prompt, to run your code, type `dotnet run` and then
|
|||
|
press Enter.
|
|||
|
|
|||
|
Output
|
|||
|

|
|||
|
```txt
|
|||
|
John Smith, Senior Associate
|
|||
|
```
|
|||
|
|
|||
|
Take a minute to review the `switch` statement that you entered.
|
|||
|
|
|||
|
Notice that the `switch` statement defines a single code block.
|
|||
|
|
|||
|
The `switch` statement defines a single code block that includes a list of
|
|||
|
`switch` sections. To the right of the switch keyword is a *switch expression*
|
|||
|
that's enclosed in parentheses.
|
|||
|
|
|||
|
Notice the list of switch sections inside the code block.
|
|||
|
|
|||
|
The `switch` code block contains a list of switch sections, each of which
|
|||
|
includes one or more switch labels. In addition, each switch section includes
|
|||
|
a statement list that will execute if the label is equal to the switch
|
|||
|
expression defined at the top of the switch statement.
|
|||
|
|
|||
|
The switch expression is evaluated against the case labels from top to bottom
|
|||
|
until a value that is equal to the switch expression is found. If none of the
|
|||
|
labels are a match, the statement list for the `default` case will be executed.
|
|||
|
If no default is included, control is transferred to the end point of the
|
|||
|
switch statement. Each label must provide a value type that matches the type
|
|||
|
specified in the switch expression.
|
|||
|
|
|||
|
> Note
|
|||
|
> The optional `default` label can appear at any position within the list of
|
|||
|
switch sections. However, most developers choose to put it last because it
|
|||
|
makes more sense (logically) to position `default` as the final option.
|
|||
|
Regardless of the position, the `default` section will be evaluated last.
|
|||
|
|
|||
|
In our example:
|
|||
|
|
|||
|
- the switch expression is `(employeeLevel)`
|
|||
|
- each switch section has a single switch label (`case` or `default`).
|
|||
|
- the matching switch section is defined by `case: 200`, since
|
|||
|
`employeeLevel = 200`.
|
|||
|
|
|||
|
Notice that each switch section is separated from the next.
|
|||
|
|
|||
|
Only one switch section is allowed to be executed. This means that execution
|
|||
|
of a switch section is not permitted to “fall through” to the next switch
|
|||
|
section. The `break` keyword is one of several ways to end a switch section
|
|||
|
before it gets to the next section. If you forget the `break` keyword (or,
|
|||
|
optionally, the `return` keyword) the compiler will generate an error.
|
|||
|
|
|||
|
#### Change the level variable value to see how the switch statement evaluates it
|
|||
|
|
|||
|
To exercise the default case, let's change the employee's level by modifying the value assignment.
|
|||
|
|
|||
|
To modify the value assigned to `employeeLevel`, update your code as follows:
|
|||
|
|
|||
|
```cs
|
|||
|
int employeeLevel = 201;
|
|||
|
```
|
|||
|
|
|||
|
Save your code file, and then run your code.
|
|||
|
|
|||
|
Enter `dotnet run` from the Terminal command prompt to run your code.
|
|||
|
|
|||
|
Notice that the output has changed.
|
|||
|
|
|||
|
Now, when you run the code, you should see the more generic title used.
|
|||
|
|
|||
|
```txt
|
|||
|
John Smith, Associate
|
|||
|
```
|
|||
|
|
|||
|
Since the `employeeLevel` doesn't match any labels, the `default` label is
|
|||
|
matched.
|
|||
|
|
|||
|
#### Modify a switch section to include multiple labels
|
|||
|
|
|||
|
Suppose our company decided to give all level 100 employees the title "Senior
|
|||
|
Associate" -- the same title as level 200 employees. As the developer, you
|
|||
|
decide to implement this by removing the first switch section belonging to the
|
|||
|
label `case 100:`, and instead allow both the `case 100:` and `case 200:` labels
|
|||
|
to execute the same switch section.
|
|||
|
|
|||
|
To modify the value assigned to employeeLevel, update your code as follows:
|
|||
|
|
|||
|
```cs
|
|||
|
int employeeLevel = 100;
|
|||
|
```
|
|||
|
|
|||
|
To assign multiple labels to the first switch section, update your code as follows:
|
|||
|
|
|||
|
```cs
|
|||
|
case 100:
|
|||
|
case 200:
|
|||
|
title = "Senior Associate";
|
|||
|
break;
|
|||
|
```
|
|||
|
|
|||
|
When you're finished making changes, your modifications should match the
|
|||
|
following code:
|
|||
|
|
|||
|
```cs
|
|||
|
int employeeLevel = 100;
|
|||
|
string employeeName = "John Smith";
|
|||
|
|
|||
|
string title = "";
|
|||
|
|
|||
|
switch (employeeLevel) {
|
|||
|
case 100:
|
|||
|
case 200:
|
|||
|
title = "Senior Associate";
|
|||
|
break;
|
|||
|
case 300:
|
|||
|
title = "Manager";
|
|||
|
break;
|
|||
|
case 400:
|
|||
|
title = "Senior Manager";
|
|||
|
break;
|
|||
|
default:
|
|||
|
title = "Associate";
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
Console.WriteLine($"{employeeName}, {title}");
|
|||
|
```
|
|||
|
|
|||
|
Save your code file, and then run your code.
|
|||
|
|
|||
|
Enter `dotnet run` from the Terminal command prompt to run your code.
|
|||
|
|
|||
|
You should see the following output:
|
|||
|
|
|||
|
```txt
|
|||
|
John Smith, Senior Associate
|
|||
|
```
|
|||
|
|
|||
|
Both of the case labels `100` and `200` are now paired with the switch section
|
|||
|
that sets the title to the string value `Senior Associate`.
|
|||
|
|
|||
|
### Recap
|
|||
|
|
|||
|
Here's the main takeaways you learned about the switch statement:
|
|||
|
|
|||
|
- Use the `switch` statement when you have one value with many possible matche
|
|||
|
s, each match requiring a branch in your code logic.
|
|||
|
- A single switch section containing code logic can be matched using one or
|
|||
|
more labels defined by the `case` keyword.
|
|||
|
- Use the optional `default` keyword to create a label and a switch section
|
|||
|
that will be used when no other case labels match.
|
|||
|
|
|||
|
---
|
|||
|
|
|||
|
## Exercise
|
|||
|
|
|||
|
### Complete a challenge activity using switch statements
|
|||
|
|
|||
|
Code challenges will reinforce what you've learned, and help you gain some
|
|||
|
confidence before continuing on.
|
|||
|
|
|||
|
### Convert to switch statements challenge
|
|||
|
|
|||
|
In this challenge, you'll rewrite an `if-elseif-else` construct as a `switch`
|
|||
|
statement. This challenge should help you see the strengths/weaknesses of the
|
|||
|
`switch` statement when compared to an `if-elseif-else` construct. Good luck.
|
|||
|
|
|||
|
### Code challenge: rewrite if-elseif-else using a switch statement
|
|||
|
|
|||
|
You'll start with code that uses an `if-elseif-else` construct to evaluate the
|
|||
|
components of a product SKU. The SKU (Stock Keeping Unit) is formatted using
|
|||
|
three coded values: `<product #>-<2-letter color code>-<size code>`. For
|
|||
|
example, a SKU value of `01-MN-L` corresponds to (sweat shirt)-(maroon)-(large),
|
|||
|
and the code outputs a description that appears as "Product: Large Maroon
|
|||
|
Sweat shirt".
|
|||
|
|
|||
|
Your challenge is to convert the `if` statement code to a `switch` statement
|
|||
|
that achieves the same result as the initial code.
|
|||
|
|
|||
|
Enter the following code into the code editor:
|
|||
|
|
|||
|
```cs
|
|||
|
// SKU = Stock Keeping Unit.
|
|||
|
// SKU value format: <product #>-<2-letter color code>-<size code>
|
|||
|
string sku = "01-MN-L";
|
|||
|
|
|||
|
string[] product = sku.Split('-');
|
|||
|
|
|||
|
string type = "";
|
|||
|
string color = "";
|
|||
|
string size = "";
|
|||
|
|
|||
|
if (product[0] == "01") {
|
|||
|
type = "Sweat shirt";
|
|||
|
} else if (product[0] == "02") {
|
|||
|
type = "T-Shirt";
|
|||
|
} else if (product[0] == "03") {
|
|||
|
type = "Sweat pants";
|
|||
|
} else {
|
|||
|
type = "Other";
|
|||
|
}
|
|||
|
|
|||
|
if (product[1] == "BL") {
|
|||
|
color = "Black";
|
|||
|
} else if (product[1] == "MN") {
|
|||
|
color = "Maroon";
|
|||
|
} else {
|
|||
|
color = "White";
|
|||
|
}
|
|||
|
|
|||
|
if (product[2] == "S") {
|
|||
|
size = "Small";
|
|||
|
} else if (product[2] == "M") {
|
|||
|
size = "Medium";
|
|||
|
} else if (product[2] == "L") {
|
|||
|
size = "Large";
|
|||
|
} else {
|
|||
|
size = "One Size Fits All";
|
|||
|
}
|
|||
|
|
|||
|
Console.WriteLine($"Product: {size} {color} {type}");
|
|||
|
```
|
|||
|
|
|||
|
Update the code to use a `switch` statement in place of the `if-elseif-else`
|
|||
|
construct.
|
|||
|
|
|||
|
Verify that your output hasn't changed.
|
|||
|
|
|||
|
No matter how you do it, your code should produce the following output:
|
|||
|
|
|||
|
Output
|
|||
|

|
|||
|
```txt
|
|||
|
Product: Large Maroon Sweat shirt
|
|||
|
```
|
|||
|
|
|||
|
```cs
|
|||
|
string sku = "01-MN-L";
|
|||
|
|
|||
|
string[] product = sku.Split('-');
|
|||
|
|
|||
|
string type = "";
|
|||
|
string color = "";
|
|||
|
string size = "";
|
|||
|
|
|||
|
switch (product[0]) {
|
|||
|
case "01":
|
|||
|
type = "Sweat shirt";
|
|||
|
break;
|
|||
|
case "02":
|
|||
|
type = "T-Shirt";
|
|||
|
break;
|
|||
|
case "03":
|
|||
|
type = "Sweat pants";
|
|||
|
break;
|
|||
|
default:
|
|||
|
type = "Other";
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
switch (product[1]) {
|
|||
|
case "BL":
|
|||
|
color = "Black";
|
|||
|
break;
|
|||
|
case "MN":
|
|||
|
color = "Maroon";
|
|||
|
break;
|
|||
|
default:
|
|||
|
color = "White";
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
switch (product[2]) {
|
|||
|
case "S":
|
|||
|
size = "Small";
|
|||
|
break;
|
|||
|
case "M":
|
|||
|
size = "Medium";
|
|||
|
break;
|
|||
|
case "L":
|
|||
|
size = "Large";
|
|||
|
break;
|
|||
|
default:
|
|||
|
size = "One Size Fits All";
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
Console.WriteLine($"Product: {size} {color} {type}");
|
|||
|
```
|