模式匹配是编译器强制的类型安全与作用域隔离机制,is后为“声明+约束”,变量仅匹配成功时存在;switch表达式支持全模式,传统switch仅支持常量;is比as更安全,属性模式须依附类型且空值需显式处理。

模式匹配不是语法糖,是编译器强制的类型安全与作用域隔离机制——is 后面写的不是“判断条件”,而是“声明 + 约束”;变量只在匹配成功时存在,编译器直接阻止误用。
必须用 switch 表达式,别碰传统 switch 语句
传统 switch 语句只认常量:字符串、整数、枚举值。写 case Person p:?直接报 CS8120 错误。
-
switch表达式(obj switch { ... })才支持类型、属性、关系、not null、嵌套等全部现代模式 - 传统语句里想用模式,只能塞进
when子句:case object o when o is Person p:—— 但这就绕回去了,不如直接用表达式 -
switch表达式强制返回值,且对enum类型自动检查穷尽性;对object或基类则不会警告漏分支,得手动加_ => throw new ArgumentException(...)
is 声明模式比 as 更安全,尤其对值类型
as 只适用于引用类型和可空值类型,对 int? 转 int 编译失败;而 is int x 完全合法,且 x 仅在匹配成功时可见。
-
if (obj is string s && s.Length > 0):s在整个&&右侧都可用,且编译器确保它非null -
as失败返回null或default,之后还得判空;is一步到位,无中间态 - 对重载了
==的类,obj != null可能抛异常;is not null是语言级检查,不调用任何用户代码
属性模式必须依附类型,且空值要显式处理
单独写 { Age: >= 18 } 会报 CS8121:“无法推断要匹配的类型”。属性模式不是独立语法,它必须嵌套在类型模式中。
- 正确写法:
person switch { Person { Age: >= 18, Name: not null } => "adult", _ => "other" } - 若
Address可能为null,不能直接写{ Address.City: "Beijing" }—— 运行时崩;得拆成两步:person is { Address: not null } and { Address.City: "Beijing" } - 每次匹配都会真实调用属性 getter,如果
Age的get里有日志或计数逻辑,会被执行 —— 别把副作用塞进属性
常量模式和关系模式混用时,or 不是万能的
is >= 18 合法,is 18 or 19 or 20 非法 —— C# 不允许用 or 连接多个常量。
- 想匹配多个离散值,改用逗号分隔的列表模式:
obj is 18 or 19 or 20❌ →obj is (18 or 19 or 20)也不行 → 正确是obj is 18 or obj is 19 or obj is 20,或更简洁地用switch表达式分支 - 范围匹配优先用关系模式:
is >= 18 and ,别拼一堆 <code>or -
not null是常量模式,可和类型模式组合:if (str is not null and string s),一次完成非空 + 类型提取
最易被忽略的一点:模式匹配不帮你做空保护。属性路径上任意一环为 null,就直接 NullReferenceException;is 不是防御性编程的替代品,该加 ?. 还得加,该拆层判断还得拆。



















