选择语句

Tip

本文是已了解至少一种编程语言并正在学习 C# 的开发人员的 “基础知识 ”部分的一部分。 如果你不熟悉编程,请先 学习入门 教程。 有关完整语法,请参阅语言参考中的 选择语句

来自另一种语言? C++、Java 和 JavaScript 都共享 C 的遗产,因此ifelseswitch C# 中读取相同的内容。 值得注意的一个区别:C# 禁止在非空 switch case 之间贯穿,每个 case 标签都可以测试模式,而不仅仅测试常量。 如果你熟悉 Python,那么 C# 的 if/else if/else 对应于 if/elif/else,而 C# 中基于模式的 switch 最接近 Python 的 match 语句。

选择语句根据条件选择运行的代码块。 C# 提供两种语句:if(可选配 else),用于根据布尔值进行分支;以及 switch,用于将一个值与多个情况进行比较。 布尔表达式是指求值结果为truefalse的任何表达式,例如比较temperature >= 25

带有ifelse的分支

if语句仅在布尔表达式为true时运行其块。 添加一个 else 代码块,以提供在条件为 false 时运行的代码:

int temperature = 28;

// An if statement runs its block only when the condition is true.
// The else block runs when the condition is false.
if (temperature >= 25)
{
    Console.WriteLine("Warm"); // => Warm
}
else
{
    Console.WriteLine("Cool");
}

ifelse 的正文是单个语句,例如赋值或方法调用。 块语句本身是一个语句,将零个或多个语句括在大括号 ({ }) 中。

许多编码标准建议将分支正文括在大括号中,即使对于单个语句也是如此。 大括号使作用域更加明确。 它可以防止一个常见错误:之后添加第二行代码时,你原本以为它会有条件地执行,结果它却会无条件执行。 只有大括号决定哪些语句属于分支。 C# 不会将空格视为有意义的字符,因此单独的缩进永远不会将空格视为有意义的字符。 即使在一行周围,大括号也是合法的:块是分支运行的单个语句。 对代码进行缩进以提高可读性,但要依靠大括号来界定代码块。

使用 else if 测试多个条件

若要在两个以上路径之间进行选择,请使用 else if 将条件串联起来。 C# 按顺序计算每个条件,并运行其条件为 true的第一个块,然后跳过其余的块。 最后,else 处理所有其余情况:

int score = 82;

// Chain conditions with else if. The first branch whose condition is
// true runs; the compiler skips the rest.
string grade;
if (score >= 90)
{
    grade = "A";
}
else if (score >= 80)
{
    grade = "B";
}
else if (score >= 70)
{
    grade = "C";
}
else
{
    grade = "F";
}

Console.WriteLine(grade); // => B

顺序在链中很重要。 由于第一个匹配条件获胜,因此首先放置最具体的条件。 在前面的示例中,先测试 score >= 80 再测试 score >= 70 可确保 82 分映射到 "B",而不是 "C"

将值与 switch 语句匹配

将单个值与许多离散事例进行比较时, switch 语句读得比长 else if 链更清晰。 同样 if,该 switch 语句是分支语句:它选择要运行的代码。 每个 case 标签列出一个要匹配的值,每个 case 节以语句 break 结尾。 将标签堆叠起来以共用同一个主体,并使用 default 部分处理与任何 case 都不匹配的值:

DayOfWeek day = DayOfWeek.Saturday;

// A switch statement compares one value against several case labels.
// Stacked labels share a body. Each section ends with break, and the
// default section runs when no case matches.
switch (day)
{
    case DayOfWeek.Saturday:
    case DayOfWeek.Sunday:
        Console.WriteLine("Weekend"); // => Weekend
        break;
    default:
        Console.WriteLine("Weekday");
        break;
}

与 C 和 Java 不同,C# 不允许执行从一个非空 case 节直接贯穿到下一个节。 包含代码的每个部分都必须以 ( break 或另一个 jump 语句(如 returngoto)结尾。 此规则可防止这些语言中共有的意外贯穿 bug。

使用 casewhen 测试模式

case标签不限于常量值。 它可以测试 模式,这是描述数据形状或值的规则。 关系模式,例如 < 0 匹配小于零的任何值。 添加一个 when 子句以附加一个额外条件,该条件也必须 true,该情形才会匹配:

int measurement = 42;

// A case label can test a pattern instead of a constant. A when clause
// adds a condition that must also be true for the case to match.
switch (measurement)
{
    case < 0:
        Console.WriteLine("Negative");
        break;
    case 0:
        Console.WriteLine("Zero");
        break;
    case > 0 when measurement % 2 == 0:
        Console.WriteLine("Positive and even"); // => Positive and even
        break;
    default:
        Console.WriteLine("Positive and odd");
        break;
}

基于模式的 case 会按从上到下的顺序进行求值,因此更具体的模式应放在更一般的模式之前。 有关模式的完整目录,请参阅 模式匹配

使用表达式选择值

ifswitch 语句决定执行哪些代码。 当需要选择 时,请使用 表达式。 表达式会求得一个值,因此凡是需要值的地方都可以使用它,例如赋值语句的右侧或作为方法参数。 C# 提供从条件运算符和 switch 表达式等替代项中选择值的表达式窗体。

条件运算符 ?:

条件运算符 ?: 根据布尔条件选择两个值之一。

有关其语法、短路行为以及选择它而非 if/else 的指导,请参阅 条件运算符 ?:

switch 表达式

表达式 switch 是与 switch 语句对应的表达式。 它不会对匹配的 case 运行代码,而是会求得一个值。 它比在语句的每个分支 switch 中赋值更简洁,当手臂不涵盖每个可能的输入时,编译器会发出警告。 表达式 switch 是模式匹配的核心部分。 若要了解何时以及如何使用它,请参阅 模式匹配switch 表达式 引用。

另见