The switch expression
In the previous lesson, the switch statement chose which code to run. Often you need something else: get a floor's name from its number and store it in a variable. With the switch statement, that would take a variable, an assignment in every branch and a break after every assignment.
Back to the elevator. Next to the buttons hangs a sign: "1—lobby, 3—cafe, everything else—offices." The sign does nothing; it only answers: name a floor and you get its name. The switch expression works like that sign: given a value, it produces a result.
int floor = 3;
string name = floor switch
{
1 => "Lobby",
3 => "Cafe",
_ => "Offices",
};
Console.WriteLine(name); // CafeLet's take the program apart:
floor switch { … }takes the value offloor, which is3, and looks for a matching line on the sign.- The line
1 => "Lobby"does not match:3is not equal to1. - The line
3 => "Cafe"matches, and the whole expression gets the value"Cafe". - That value goes into the variable
name, and the program printsCafe.
The parts of a switch expression
Each line like 3 => "Cafe" is called an arm of the expression. The whole thing is made of four parts:
- the value before the word
switch—what is being checked, herefloor; - the arms in braces: a value to the left of
=>, a result to the right, and a comma after each arm; - the
_arm means "everything else": it matches any value, likedefaultin theswitchstatement; - a semicolon after the closing brace: everything from
string nameto;is one statement.
The arms are checked from top to bottom, and the first matching one wins. That is why _ goes last. An arm below it could never match, and the compiler rejects such code.
Every result must fit the variable on the left. Here each arm gives a string, and an arm with a number, 3 => 42, would not compile.
Expression and statement
It is the same pair as if and ?:: a statement runs code, and an expression has a value. You don't have to store the value of a switch expression in a variable; you can pass it straight to Console.WriteLine:
int day = 7;
Console.WriteLine(day switch
{
6 => "Saturday",
7 => "Sunday",
_ => "workday",
}); // SundayThe expression day switch { … } gives "Sunday", and that value goes straight into Console.WriteLine.
An arm of the expression holds a single value, not statements: you cannot put a break or several lines of code there. When each case needs several actions, use the switch statement.
Interviewers sometimes ask how the switch expression differs from the switch statement. The short answer: the statement runs a branch's code, the expression computes a value, and its arms need no break.
This is where the sign analogy breaks down. If the sign has no line for a floor, the sign stays silent. A switch expression cannot stay silent: without a matching arm, it stops the program.
Common mistake
The _ arm is missing:
int floor = 4;
string name = floor switch // ✗
{
1 => "Lobby",
3 => "Cafe",
};
Console.WriteLine(name);warning CS8509: The switch expression does not handle all possible values of its input type (it is not exhaustive). For example, the pattern '0' is not covered.The program compiles, but with this warning: the compiler noticed that 0 and many other numbers have no arm. When it runs with floor = 4, no arm matches, and the program stops at this line with an exception:
Unhandled exception. System.Runtime.CompilerServices.SwitchExpressionException: Non-exhaustive switch expression failed to match its input.A switch statement without default would run nothing in this case. The expression, though, must have a value for name, and there is none to take. Add the arm _ => "Offices", and both the warning and the exception go away.
Key points
- A
switchexpression picks a result by value:floor switch { 1 => "Lobby", _ => "Offices" }. - The arms are checked from top to bottom; the
_arm matches any value and goes last. - The
switchstatement runs a branch's code, while theswitchexpression gives a value and needs nobreak. - Without a matching arm, the program stops with a
SwitchExpressionException, and the compiler warns about it in advance:CS8509.