CodeGym /课程 /C# SELF /switch-表达式 和新模式

switch-表达式 和新模式

C# SELF
第 10 级, 课程 5
可用

1. 入门

你已经会写这样的代码了:

switch (color)
{
    case "red":
        Console.WriteLine("停!");
        break;
    case "yellow":
        Console.WriteLine("请等待...");
        break;
    case "green":
        Console.WriteLine("可以走了!");
        break;
    default:
        Console.WriteLine("这是什么颜色?");
        break;
}

但如果我们想根据输入参数给变量赋不同的值,比如从函数里返回一个基于数字的字符串呢?在 switch-表达式 出现之前,只能写成这样:

string meaning;
switch (number)
{
    case 42:
        meaning = "生命、宇宙以及一切的终极答案";
        break;
    case 7:
        meaning = "幸运数字";
        break;
    default:
        meaning = "普通数字";
        break;
}

感觉对21世纪的语言来说有点不优雅,对吧?我们更想直接返回值,就像函数式语言那样。

这时候 switch-表达式 就登场了 —— 这是C# 8.0起最酷(也最新)的特性之一。

2. switch-表达式:让人想抱一抱的语法

对比:语句和表达式
经典的 switchstatement(“语句”),而 switch-表达式expression,也就是它会计算出一个值,可以直接赋给变量或者 return。

switch-表达式的结构:


var result = value switch
{
    pattern1 => expression1,
    pattern2 => expression2,
    _       => defaultExpression // “下划线”就是“否则”
};
switch-表达式 的语法

比如:

int number = 42;
string meaning = number switch
{
    42 => "生命、宇宙以及一切的终极答案",
    7  => "幸运数字",
    _  => "普通数字"
};
Console.WriteLine(meaning); // => 生命、宇宙以及一切的终极答案

很简洁、可读,没有一堆代码,也没有 break;

注意: 下划线 _ 就是“匹配所有剩下的情况”,等价于 default

3. switch-表达式 和 pattern:怎么配合用

这才是真正的乐趣开始。在 switch-表达式 里,不光能用普通值,还能用 pattern:比如区间判断、类型判断、对象属性判断、解构(把对象拆成部分),甚至还能用 combinatorial patternsandornot)。

switch-表达式里的 pattern 示例

常量 pattern
就是我们上面做的那种:和 427 等等比较。

区间和比较

int age = 17;
string category = age switch
{
    < 18 => "未成年人",
    >= 18 and <= 65 => "成年人",
    > 65 => "老年人",
    _ => "未知年龄段"
};
Console.WriteLine(category);

顺便说一句 —— 可以一起用多个条件!C# 越来越有表现力了。

类型 pattern (Type Patterns)

比如我们有个对象,类型可能不同(比如 object value;)。我们可以这样处理不同类型:

object value = 3.14;
string description = value switch
{
    int i => $"整数: {i}",
    double d => $"小数: {d:F2}",
    string s => $"这是字符串: '{s}'",
    null => "null!",
    _ => "其他类型"
};
Console.WriteLine(description); // => 小数: 3.14

属性 pattern 和位置 pattern (Property Patterns 和 Positional Patterns)

从 C# 8 开始,我们可以直接在 switch-表达式 里判断属性值。

对象示例

public class User
{
    public string Name { get; set; }
    public int Age { get; set; }
}

User user = new User { Name = "安娜", Age = 17 };
string welcome = user switch
{
    { Age: < 18 } => $"你好, {user.Name}! 你是青少年。",
    { Age: >= 18 and <= 65 } => $"嗨, {user.Name}! 成年生活很棒。",
    { Age: > 65 } => $"欢迎, {user.Name}! 永远欢迎你。",
    _ => "未知年龄"
};
Console.WriteLine(welcome);

这里大括号里的 { Age: < 18 } 是 property pattern,也就是只判断对象的某个属性。

4. C# 11-14 新 pattern

C# 越来越简洁灵活。最近加了 combinatorial patternsandornot,还有更强的 positional patterns。我们来看看。

逻辑 pattern:andornot

你可以像写逻辑表达式那样组合条件!

int temperature = 25;
string result = temperature switch
{
    < 0 => "很冷!",
    >= 0 and < 20 => "有点凉",
    >= 20 and < 30 => "很舒服",
    >= 30 or <= -30 => "极端!",
    _ => "奇怪的温度"
};

如果想排除某些情况,也可以:

int score = 80;
string grade = score switch
{
    >= 90 => "优秀",
    >= 60 and not >= 90 => "良好",
    _ => "差"
};

解构 (Positional Patterns)

如果你有 struct 或 record,支持解构,C# 允许你在 switch-表达式 里直接拆对象:

public record Point(int X, int Y);

Point p = new Point(10, 20);
string desc = p switch
{
    (0, 0) => "原点",
    (var x, 0) => $"在X轴上, X={x}",
    (0, var y) => $"在Y轴上, Y={y}",
    (var x, var y) when x == y => $"在对角线: {x}",
    _ => $"在点 ({p.X}, {p.Y})"
};
Console.WriteLine(desc); // => 在点 (10, 20)

5. 什么时候用 switch-表达式,为什么用

在现代C#里,switch-表达式 不只是个“新潮玩意”,而是真正能帮你少写废话,让代码更紧凑、更好测、更好维护的利器。写 parser、命令处理、业务逻辑、规则配置等场景,尤其是需要根据复杂条件分支(不仅仅是值,还有类型、区间、属性、组合)时特别有用。

面试时

  • 你会怎么处理用户的不同回答?
  • 怎么让函数根据类型和值返回不同结果?
  • 怎么优雅地加新规则,不用一堆 if-else?

秀一个带 pattern 的 switch-表达式!这立马能体现你对新特性的掌握和你的代码风格。

表格:switch 语句 vs switch-表达式

特点 switch statement switch expression
类型 语句 (statement) 表达式 (expression)
需要 break 必须 不需要
能否返回值 只能通过变量 可以直接返回值
能否用 pattern 部分支持 完全支持(类型、属性等)
坑点 容易忘 break 所有分支都要返回值

6. 常见错误和小坑

  • 新手经常搞混 switch 语句("statement")和 switch-表达式("expression")。比如忘了 switch-表达式 不需要 break;,而且每个分支都必须返回值。
  • 如果忘了写 _ 分支,编译器会提醒你:“那如果都不匹配呢?”
  • switch-表达式 里不能用 goto(这其实挺好!)。
  • 如果有重复的条件(比如两个一样的 pattern),编译器也不会放过你。
  • 注意 switch-表达式 返回值的类型:它必须和你赋值的变量类型兼容。
2
任务
C# SELF, 第 10 级, 课程 5
已锁定
简单的 switch 表达式和模式匹配
简单的 switch 表达式和模式匹配
2
任务
C# SELF, 第 10 级, 课程 5
已锁定
根据长度和字符验证密码
根据长度和字符验证密码
1
调查/小测验
常量和关键字 var第 10 级,课程 5
不可用
常量和关键字 var
常量、结构体、枚举和 switch
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION