Skip to content

C# - 嵌套Switch语句

C# - 嵌套的 switch 语句及现代替代方案

Section titled “C# - 嵌套的 switch 语句及现代替代方案”

嵌套的 switch 语句是将一个 switch 语句放置在另一个 switch 语句的 case 块中。尽管这在语法上是可行的,但它通常表明一种复杂的决策结构,难以阅读、维护和测试。

以下是嵌套 switch 语句的基本结构:

switch (outerExpression)
{
case outerValue1:
// 外部 case 1 的代码
switch (innerExpression)
{
case innerValue1:
// 内部 case 1 的代码
break;
case innerValue2:
// 内部 case 2 的代码
break;
default:
// 内部 default 的代码
break;
}
break; // 外部 case 1 结束
case outerValue2:
// 外部 case 2 的代码
break;
default:
// 外部 default 的代码
break;
}

让我们来看一个根据员工部门和角色确定其职责的例子。这展示了嵌套如何变得繁琐。

string department = "IT";
string role = "Manager";
switch (department)
{
case "IT":
Console.WriteLine("Department: Information Technology");
switch (role)
{
case "Developer":
Console.WriteLine("Role: Responsible for coding.");
break;
case "Manager":
Console.WriteLine("Role: Oversees IT projects.");
break;
default:
Console.WriteLine("Invalid IT Role!");
break;
}
break;
case "HR":
Console.WriteLine("Department: Human Resources");
// 另一个用于 HR 角色的 switch 会放在这里
break;
default:
Console.WriteLine("Invalid Department!");
break;
}
// 输出:
// Department: Information Technology
// Role: Oversees IT projects.

现代替代方案:使用元组的 switch 表达式

Section titled “现代替代方案:使用元组的 switch 表达式”

自 C# 8.0 起,switch 表达式提供了一种更简洁、更易读的方式来处理复杂的条件逻辑。通过将它们与元组结合使用,我们可以完全消除嵌套,创建更清晰、更“扁平化”的结构。

最佳实践: 对于多级决策,优先使用带有元组的 switch 表达式,而不是嵌套的 switch 语句。这显著提高了代码的可读性和可维护性。

这是上一个示例的相同逻辑,使用现代 C# 功能重写。

string department = "IT";
string role = "Manager";
// 使用元组 (department, role) 作为 switch 表达式的输入
string responsibility = (department, role) switch
{
("IT", "Developer") => "Responsible for coding.",
("IT", "Manager") => "Oversees IT projects.",
("IT", "Tester") => "Ensures software quality.",
("HR", "Recruiter") => "Manages the hiring process.",
("HR", "Trainer") => "Conducts training sessions.",
// 弃元字符 `_` 用作特定位置的通配符/默认值
("IT", _) => "Invalid IT Role!",
("HR", _) => "Invalid HR Role!",
// 单个弃元字符是整体的默认情况
_ => "Invalid Department or Role!"
};
Console.WriteLine($"Responsibility for {department}/{role}: {responsibility}");
// 输出:
// Responsibility for IT/Manager: Oversees IT projects.

1. switch 语句中缺少 break: 在传统的 switch 语句(非表达式)中,忘记在 case 块末尾添加 break 是一个常见的编译时错误。每个非空的 case 都必须显式退出 switch(通常使用 break、return 或 goto)。

2. 非穷尽的 switch 表达式: switch 表达式必须是穷尽的。它必须处理输入的所有可能值。如果不是,你将收到编译器警告,并且如果遇到未处理的值,运行时将抛出 SwitchExpressionException。弃元模式 _ 用于创建默认情况并确保穷尽性。

3. 调试提示: 如果你的 switch 表达式没有匹配到你期望的 case,请仔细检查字符串字面量中是否有简单的拼写错误,并确保变量的值是你所认为的。在 switch 表达式之前使用调试器检查 department 和 role 的值。

对于更复杂的场景,请考虑以下高级模式:

  • 带有 when 子句的 switch 表达式,用于更详细的条件(例如,case ("IT", _) when user.IsAdmin => ...)。
  • 面向对象设计: 如果逻辑变得非常复杂,这可能是一个信号,表明你应该使用多态性(例如,创建 IT 类和 HR 类,它们继承自一个共同的 Department 基类或接口)。