0

0

C# 中的模式匹配递归模式如何匹配树结构?

畫卷琴夢

畫卷琴夢

发布时间:2025-10-24 14:55:01

|

903人浏览过

|

来源于php中文网

原创

递归模式结合record可自然匹配树结构,如用{ Left: null, Right: null }判断叶子节点,或嵌套模式识别子树形状,还可用于表达式树求值与简化,如Add(var e, Constant(0))映射为Simplify(e),实现声明式结构解析。

c# 中的模式匹配递归模式如何匹配树结构?

在 C# 中,模式匹配的递归模式(recursive patterns)可以自然地用来匹配树结构。通过结合 递归数据类型位置模式(positional patterns),你可以清晰地解构并判断节点结构、字段值或嵌套关系。

定义树结构

以二叉树为例,每个节点包含一个值和左右子节点:

public record TreeNode(int Value, TreeNode? Left, TreeNode? Right);

这是一个典型的不可变树结构,使用 record 支持基于值的相等性和位置解构,这是实现递归模式匹配的基础。

使用递归模式进行匹配

你可以用 switch 表达式is 表达式 来匹配树的形状。例如,判断是否为叶子节点(无子节点):

bool IsLeaf(TreeNode? node) => node is { Left: null, Right: null };

更复杂的结构可以用嵌套的位置模式。比如判断一个节点左子是叶子节点:

bool HasLeftLeaf(TreeNode? node) => node is { Left: { Left: null, Right: null } };

你也可以结合常量和范围模式。例如,匹配某个特定形状的子树:

InsCode
InsCode

InsCode 是CSDN旗下的一个无需安装的编程、协作和分享社区

下载
string Classify(TreeNode? node) => node switch { null => "Empty", { Value: 0, Left: null, Right: null } => "Zero leaf", { Value: var v, Left: { Value: var lv }, Right: null } when v > lv => "Right unbalanced", { Value: _, Left: not null, Right: not null } => "Full node", _ => "Other" };

实际应用场景

递归模式特别适合用于表达式树的分析。比如定义一个简单的算术表达式树:

public abstract record Expr; public record Constant(int Value) : Expr; public record Add(Expr Left, Expr Right) : Expr; public record Multiply(Expr Left, Expr Right) : Expr;

然后你可以用模式匹配来“解释”或优化表达式:

int Evaluate(Expr expr) => expr switch { Constant(int value) => value, Add(var left, var right) => Evaluate(left) + Evaluate(right), Multiply(var left, var right) => Evaluate(left) * Evaluate(right), _ => throw new NotSupportedException() };

还可以做代数简化,比如识别 x + 0 这样的模式:

Expr Simplify(Expr expr) => expr switch { Add(var e, Constant(0)) => Simplify(e), Add(Constant(0), var e) => Simplify(e), Multiply(var e, Constant(1)) => Simplify(e), // 更多规则... Add(var l, var r) => new Add(Simplify(l), Simplify(r)), _ => expr };

基本上就这些。递归模式让 C# 能以声明式方式处理复杂嵌套结构,尤其适合语法树、配置树或领域模型的条件判断与转换。关键是使用 record 提供的解构能力和模式中的嵌套匹配逻辑。不复杂但容易忽略的是:确保属性或位置可被编译器静态分析,否则模式无法生效。

相关专题

更多
数据类型有哪几种
数据类型有哪几种

数据类型有整型、浮点型、字符型、字符串型、布尔型、数组、结构体和枚举等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

306

2023.10.31

php数据类型
php数据类型

本专题整合了php数据类型相关内容,阅读专题下面的文章了解更多详细内容。

222

2025.10.31

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

318

2023.08.02

c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

232

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

437

2024.03.01

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1468

2023.10.24

switch语句用法
switch语句用法

switch语句用法:1、Switch语句只能用于整数类型,枚举类型和String类型,不能用于浮点数类型和布尔类型;2、每个case语句后面必须跟着一个break语句,以防止执行其他case的代码块,没有break语句,将会继续执行下一个case的代码块;3、可以在一个case语句中匹配多个值,使用逗号分隔;4、Switch语句中的default代码块是可选的等等。

534

2023.09.21

Java switch的用法
Java switch的用法

Java中的switch语句用于根据不同的条件执行不同的代码块。想了解更多switch的相关内容,可以阅读本专题下面的文章。

417

2024.03.13

Java JVM 原理与性能调优实战
Java JVM 原理与性能调优实战

本专题系统讲解 Java 虚拟机(JVM)的核心工作原理与性能调优方法,包括 JVM 内存结构、对象创建与回收流程、垃圾回收器(Serial、CMS、G1、ZGC)对比分析、常见内存泄漏与性能瓶颈排查,以及 JVM 参数调优与监控工具(jstat、jmap、jvisualvm)的实战使用。通过真实案例,帮助学习者掌握 Java 应用在生产环境中的性能分析与优化能力。

19

2026.01.20

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Bootstrap 5教程
Bootstrap 5教程

共46课时 | 2.9万人学习

【web前端】Node.js快速入门
【web前端】Node.js快速入门

共16课时 | 2万人学习

Go语言实战之 GraphQL
Go语言实战之 GraphQL

共10课时 | 0.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号