C#模式匹配详解

一、模式匹配核心概念

1.什么是模式匹配?

        模式匹配是一种检查数据结构是否满足特定条件并提取信息的机制,取代传统的 if-else 或 switch 逻辑,使代码更简洁、安全。

2.核心优势

  • 简洁性:减少类型检查和转换的冗余代码
  • 安全性:编译时检查模式的有效性(如属性是否存在)
  • 表达力:支持嵌套、递归和逻辑组合模式

二、核心模式类型与语法

1.类型模式(Type Pattern)

  • 用途:检查对象是否为指定类型,并提取变量
  • 语法:变量  is  类型  标识符
object obj = "HaHaHa"
if (obj is string s)
{Console.WriteLine("s.length"); //直接使用s,无需显式转换
}//注意:匹配失败时s不会被赋值

2.常量模式(Constant Pattern)

  • 用途:匹配常量值(如整数、字符串、null)
  • 语法:变量  is  [常量值]
int number = 1;
if (number is 1)
{Console.WriteLine("值为1");
}string str = null;
if(text is null)
{Console.WriteLine("空值");
}

3.变量模式(Var Pattern)

  • 用途:将值捕获到临时变量,通常结合 when 使用
object obj = 3.14;
if (obj is var temp && temp is double) 
{Console.WriteLine($"Double value: {temp}");
}

4.属性模式(Property Pattern)

  • 用途:匹配对象的属性值
class Person 
{public string Name { get; set; }public int Age { get; set; }
}Person p = new Person { Name = "VTheshow", Age = 100 };if (p is { Name: "VTheshow", Age: >= 18 }) 
{Console.WriteLine("VTheshow年龄大于18");
}

    5.元组模式(Tuple Pattern)

    • 用途:同时匹配多个值的元组
    var point = (x: 0, y: 1);if (point is (0, 1)) 
    {Console.WriteLine("坐标匹配");
    }// 结合类型和属性
    var result = point switch 
    {(0, 0) => "原点",(var x, var y) when x == y => "对角线",_ => "其他"
    };

    6.位置模式(Positional Pattern)

    • 用途:匹配解构后的对象(需实现 Deconstruct 方法)
    public record Point(int X, int Y); // 自动生成 DeconstructPoint pt = new Point(2, 3);
    if (pt is (2, 3)) 
    {Console.WriteLine("匹配坐标 (2,3)");
    }

    7.递归模式(Recursive Pattern)

    • 用途:嵌套组合多种模式
    if (obj is Person { Name: "HaHa", Age: int age } && age > 20) 
    {Console.WriteLine("HaHa 年龄超过 20");
    }

    8.逻辑模式(Logical Pattern)

    • C#9.0+支持:使用and、or、not组合条件
    int num = 15;
    if (num is > 10 and < 20) 
    {Console.WriteLine("介于 10 和 20 之间");
    }string text = "effective value"
    if (text is not null and not "unknown") 
    {Console.WriteLine("有效值");
    }

    9.列表模式(List Pattern)

    • C#11+支持:匹配数组或列表的元素
    int[] numbers = { 1, 2, 3 };if (numbers is [1, 2, 3]) 
    {Console.WriteLine("完全匹配");
    }if (numbers is [1, .. var rest]) 
    {Console.WriteLine($"剩余元素数量: {rest.Length}"); // 输出 2
    }// 匹配任意长度的列表
    if (numbers is [.., 3]) 
    {Console.WriteLine("以 3 结尾");
    }

    三、switch表达式

    • 用途:简化switch语句,直接返回值
    string Describe(object obj) => obj switch 
    {int i when i > 0 => "正整数",double d => $"双精度数: {d}",string s => $"字符串: {s}",null => "空值",_ => "未知类型"
    };Console.WriteLine(Describe(5)); // 输出 "正整数"

    注意事项

    • 模式顺序:switch 分支按顺序匹配,优先放置具体模式
    • 穷尽性检查:使用 _ 默认分支处理未覆盖的情况
    • 性能:模式匹配通常编译为高效代码,无需担心性能损失

    四、实际应用场景

    1.替代类型检查与转换

    class Circle 
    {public float Radius { get; set; }
    }// 传统写法
    if (shape is Circle) 
    {Circle c = (Circle)shape;Console.WriteLine(c.Radius);
    }// 模式匹配写法
    if (shape is Circle c) 
    {Console.WriteLine(c.Radius);
    }

    2.处理复杂条件

    public class IncomeData 
    {public decimal Income { get; set; } public bool IsCitizen { get; set; } 
    }string GetTaxCategory(IncomeData data) => data switch 
    {{ Income: < 10000 } => "低收入",{ Income: >= 10000 and < 50000, IsCitizen: true } => "中等收入公民",{ Income: >= 50000 } => "高收入",_ => "其他"
    };

    关键点总结

    • 属性模式的依赖:属性模式要求目标类型(如 IncomeData)必须包含对应的属性(如 Income 和 IsCitizen),且属性可访问(通常是 public
    • 模式匹配的优势:这种写法比传统的 if-else 更简洁,尤其是当条件涉及多个属性或嵌套对象时
    • 编译时安全:如果拼写错误(如写成 Incom 而不是 Income),编译器会直接报错,避免运行时错误

    3.解构嵌套对象

    if (student is { Address: { City: "Beijing", ZipCode: "100000" } }) 
    {Console.WriteLine("北京学生");
    }

    五、版本支持

    C#版本支持特性
    7.0基本类型模式、常量模式
    8.0switch 表达式、递归模式、属性模式
    9.0逻辑模式 (and/or/not)
    10.0扩展属性模式(支持嵌套属性)
    11.0列表模式、模式匹配 Span<char>

    本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/71220.shtml

    如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

    相关文章

    not support ClassForName

    com.alibaba.fastjson2.JSONException: not support ClassForName : java.lang.String, you can config JSONReader.Feature.SupportClassForName 官方说明中提到默认关闭&#xff0c; 可通过配置开启 JSON.config(JSONReader.Feature.SupportClassForName);

    在VSCode 中使用通义灵码最新版详细教程

    在 VSCode 中使用通义灵码&#xff1a;最新版详细教程与使用场景 Visual Studio Code&#xff08;简称 VSCode&#xff09;是一款由微软开发的轻量级、功能强大的开源代码编辑器&#xff0c;支持多种编程语言&#xff0c;深受开发者喜爱。而通义灵码&#xff08;TONGYI Lingma…

    不要升级,Flutter Debug 在 iOS 18.4 beta 无法运行,提示 mprotect failed: Permission denied

    近期如果有开发者的 iOS 真机升级到 18.4 beta&#xff0c;大概率会发现在 debug 运行时会有 Permission denied 的相关错误提示&#xff0c;其实从 log 可以很直观看出来&#xff0c;就是 Dart VM 在初始化时&#xff0c;对内核文件「解释运行&#xff08;JIT&#xff09;」时…

    《HarmonyOS Next × ArkTS框架:从AI模型压缩到智能家居控制的端侧开发指南》

    随着智能家居设备的普及,用户对智能化体验的需求日益增长。HarmonyOS NEXT通过API12及以上版本提供的AI能力,为开发者打造了更高效的智能家居解决方案。本文将以家庭环境控制为垂域,结合语音交互、设备联动与场景决策等核心功能,详解如何利用分布式AI框架与Python技术栈实现…

    数据结构:反射 和 枚举

    目录 一、反射 1、定义 2、反射相关的类 3、Class类 &#xff08;2&#xff09;常用获得类中属性相关的方法&#xff1a; &#xff08;3&#xff09;获得类中注解相关的方法&#xff1a; &#xff08;4&#xff09;获得类中构造器相关的方法&#xff1a; &#xff08;…

    【设计原则】里氏替换原则(LSP):构建稳健继承体系的黄金法则

    深入理解里氏替换原则&#xff08;LSP&#xff09;及其在C#中的实践 一、什么是里氏替换原则&#xff1f;二、为什么需要LSP&#xff1f;三、经典违反案例&#xff1a;矩形与正方形问题四、正确的设计实践方案1&#xff1a;通过接口分离方案2&#xff1a;使用抽象类 五、LSP的关…

    基于Electron的应用程序安全测试基础 — 提取和分析.asar文件的案例研究

    目录&#xff1a; 4.4. 案例研究 4.4.2. 情况描述 4.4.3. 信息收集 4.4.3.2. 检查隐藏目录&#xff08;点目录&#xff09;的可能性 4.4.3.3. 使用 DB Browser for SQLite 打开 .db 文件 4.4.3.4. 寻找加密算法 4.4.3.5. 找到加密算法 4.4.3.6. 理解加密流程 4.4.3.7. 找到“Ke…

    【Delphi】如何解决使用webView2时主界面置顶,而导致网页选择文件对话框被覆盖问题

    一、问题描述&#xff1a; 在Delphi 中使用WebView2控件&#xff0c;如果预先把主界面置顶&#xff08;Self.FormStyle : fsStayOnTop;&#xff09;&#xff0c;此时&#xff0c;如果在Web页面中有使用&#xff08;<input type"file" id"fileInput" acc…

    ASP.NET Core 3.1 修改个别API返回JSON序列化格式

    ASP.NET Core 3.0及之后的版本中&#xff0c;默认的JSON格式化器是基于System.Text.Json的。返回json格式采用camelCase&#xff08;第一个单词首字母小写&#xff0c;后面单词首字母大写&#xff09;。如果想改为PascalCase&#xff0c;可以全局设置PropertyNamingPolicy nul…

    有关Java中的集合(2):Map<T>(底层源码分析)

    学习目标 核心掌握Map集合 1.Map<K,V> ● 实现了Map接口的集合对象的集合元素&#xff1a; 成对的值 key-value 键值对 ● key对象是不能重复的. value可以重复。 ● 核心: 根据key获得value。 1.1 层级 public interface Map<K, V> {}1.2 常用方法 1.3 使用方法…

    windows电脑上安装llama-factory实现大模型微调

    一、安装环境准备 这是官方给的llama-factory安装教程&#xff0c;安装 - LLaMA Factory&#xff0c;上面介绍了linux系统上以及windows系统上如何正确安装。大家依照安装步骤基本能够完成安装&#xff0c;但是可能由于缺少经验或者相关的知识导致启动webUi界面运行相应内容时…

    每日一题——接雨水

    接雨水问题详解 问题描述 给定一个非负整数数组 height&#xff0c;表示每个宽度为 1 的柱子的高度图。计算按此排列的柱子&#xff0c;下雨之后能接多少雨水。 示例 示例 1&#xff1a; 输入&#xff1a;height [0,1,0,2,1,0,1,3,2,1,2,1] 输出&#xff1a;6 解释&#…

    Ubuntu 创建新用户及设置权限

    1、新建用户 sudo adduser username 其中username是你要创建的用户的用户名&#xff0c;然后设置密码和相关信息就可以了 2、给新用户sudo权限 新创建的用户没有root权限&#xff0c;我们执行以下命令给用户sudo权限 sudo usermod -a -G adm username sudo usermod -a -G s…

    商米科技前端工程师(base上海)内推

    1.根据原型或高保真设计&#xff0c;开发web、H5、小程序等类型的前端应用&#xff1b; 2.在指导下&#xff0c;高质量完成功能模块的开发&#xff0c;并负责各功能模块接口设计工作&#xff1b; 3.负责产品及相关支撑系统的开发及维护工作&#xff0c;不断的优化升级&#x…

    HTTP四次挥手是什么?

    四次挥手&#xff0c;这是TCP协议用来关闭连接的过程。四次挥手是确保两个主机之间能够安全、可靠地关闭连接的重要机制。我会用简单易懂的方式来讲解&#xff0c;帮助你理解它的原理和过程。 1. 什么是四次挥手&#xff1f; 定义 四次挥手是TCP协议用来关闭连接的过程。它通…

    使用 REINFORCE 算法强化梯度策略

    一、整体概述 此代码利用 REINFORCE 算法&#xff08;一种基于策略梯度的强化学习算法&#xff09;来解决 OpenAI Gym 中的 CartPole-v1 环境问题。CartPole-v1 环境的任务是控制一个小车&#xff0c;使连接在小车上的杆子保持平衡。代码通过构建一个神经网络作为策略网络&…

    使用Python自动生成图文并茂的网页分析报告

    在数据分析中&#xff0c;不管是市场研究还是科学分析&#xff0c;经常需要使用Python进行数据分析并生成图表报告。一般使用Python生成和展示图表时都是使用matplotlib 库生成静态图片文件&#xff0c;这种方式不便之处是不方便跟动态文字段落结合在一起&#xff0c;也不方便分…

    【iOS】小蓝书学习(七)

    小蓝书学习&#xff08;七&#xff09; 前言第47条&#xff1a;熟悉系统框架第48条&#xff1a;多用枚举块&#xff0c;少用for循环第50条&#xff1a;构建缓存使选用NSCache而非NSDictionary第51条&#xff1a;精简initialize与load的实现代码第52条&#xff1a;别忘了NSTimer…

    C语言复习4:有关数组的基础常见算法

    # 数组的常见算法 - 查找算法 1. 基本查找/顺序查找 2. 二分查找/折半查找 3. 插值查找 4. 分块查找 5. 哈希查找 6. 树表查找 7. 斐波那契查找 - 排序算法&#xff08;顾名思义&#xff0c;就是把没有顺序的…

    Ollama 的庐山真面目

    Ollama 运行方式分析 本地推理条件&#xff08;GPU/CPU/RAM&#xff09;&#xff1a;Ollama 支持在本地电脑进行大模型推理&#xff0c;但需要满足一定的硬件条件。一般来说&#xff0c;GPU 有助于加速推理&#xff0c;特别是显存较大的 GPU 能够加载更大的模型&#xff1b;如果…