ECMA-334 C# Language Specification15.7.2: The switch statement |
The switch statement selects for execution a statement list having an associated switch label that corresponds to the value of the switch expression.
(
expression
)
switch-block
{
switch-sections
opt }
switch-section
switch-sections
switch-section
switch-labels
statement-list
switch-label
switch-labels
switch-label
constant-expression
:
:
A switch-statement
consists of the keyword switch, followed by a parenthesized expression (called the switch expression), followed by a switch-block
. The switch-block
consists of zero or more switch-section
s, enclosed in braces. Each switch-section
consists of one or more switch-label
s followed by a statement-list
(15.2.1).
The governing type of a switch statement is established by the switch expression. If the type of the switch expression is sbyte , byte , short , ushort , int , uint , long , ulong , char , string, or an enum-type
, then that is the governing type of the switch statement. Otherwise, exactly one user-defined implicit conversion (13.4) must exist from the type of the switch expression to one of the following possible governing types: sbyte , byte , short , ushort , int , uint , long , ulong , char , string. If no such implicit conversion exists, or if more than one such implicit conversion exists, a compile-time error occurs.
The constant expression of each case label must denote a value of a type that is implicitly convertible (13.1) to the governing type of the switch statement. A compile-time error occurs if two or more case labels in the same switch statement specify the same constant value.
There can be at most one default label in a switch statement.
A switch statement is executed as follows:
If the end point of the statement list of a switch section is reachable, a compile-time error occurs. This is known as the "no fall through" rule.
is valid because no switch section has a reachable end point. Unlike C and C++, execution of a switch section is not permitted to "fall through" to the next switch section, and the example
switch (i) {
case 0:
CaseZero();
break;
case 1:
CaseOne();
break;
default:
CaseOthers();
break;
}
results in a compile-time error. When execution of a switch section is to be followed by execution of another switch section, an explicit goto case or goto default statement must be used:
switch (i) {
case 0:
CaseZero();
case 1:
CaseZeroOrOne();
default:
CaseAny();
}
end example]
switch (i) {
case 0:
CaseZero();
goto case 1;
case 1:
CaseZeroOrOne();
goto default;
default:
CaseAny();
break;
}
Multiple labels are permitted in a switch-section
.
is valid. The example does not violate the "no fall through" rule because the labels case 2: and default: are part of the same
switch (i) {
case 0:
CaseZero();
break;
case 1:
CaseOne();
break;
case 2:
default:
CaseTwo();
break;
}
switch-section
. end example]
end note]
switch (i) {
default:
CaseAny();
break;
case 1:
CaseZeroOrOne();
goto default;
case 0:
CaseZero();
goto case 1;
}
end note]
switch (i) {
case 0:
while (true) F();
case 1:
throw new ArgumentException();
case 2:
return;
}
end example]
void DoCommand(string command) {
switch (command.ToLower()) {
case "run":
DoRun();
break;
case "save":
DoSave();
break;
case "quit":
DoQuit();
break;
default:
InvalidCommand(command);
break;
}
}
When the governing type of a switch statement is string, the value null is permitted as a case label constant.
The statement-list
s of a switch-block
may contain declaration statements (15.5). The scope of a local variable or constant declared in a switch block is the switch block.
Within a switch block, the meaning of a name used in an expression context must always be the same (14.5.2.1).
The statement list of a given switch section is reachable if the switch statement is reachable and at least one of the following is true:
The end point of a switch statement is reachable if at least one of the following is true: