首页 > 编程语言 >深入解析C#中的模式匹配:简洁高效的功能探索

深入解析C#中的模式匹配:简洁高效的功能探索

时间:2024-05-31 12:33:04浏览次数:23  
标签:Console C# 模式 int switch 表达式 WriteLine 解析 模式匹配

模式匹配是编程领域中一种强大的工具,用于检测表达式是否符合特定条件,C#通过一系列丰富且灵活的模式表达式与语句,极大地简化了这一过程。本文将逐一剖析C#提供的模式匹配特性,揭示其背后的简洁逻辑与强大功能。

C#模式匹配核心组件

C#模式匹配围绕两个基本构建块展开:表达式/语句模式。关键的表达式/语句包括is表达式、switch语句以及switch表达式,而模式则涵盖声明模式、类型模式、常量模式等多种类型,每种模式都有其独特的应用场景。

声明模式和类型模式:类型检验的双刃剑

声明模式类型模式虽逻辑相似,均用于检验表达式的运行时类型,但前者在匹配成功后还会将结果赋值给变量,体现了更高的便捷性。例如,利用is表达式进行类型检查并分配变量,不仅代码精简,还隐含了对null值的检查。

object obj = "Hello";
if (obj is string str)
    Console.WriteLine(str);

与之对比,类型模式不直接分配变量,但结合as操作符也能达到类似效果,只是代码略显冗余。
switch的多样运用
switch语句和表达式展示了模式匹配的灵活性,它们能够基于不同的模式进行复杂的逻辑分支处理。无论是基于类型、声明的直接匹配,还是通过逻辑组合模式进行更细腻的控制流管理,switch都显得游刃有余。

return obj switch
{
    int i => 1,
    string s => s.Length,
    null => 3,
    _ => throw new ArgumentException("未知类型")
};

常量模式至逻辑模式:从简单到复杂的

  • 常量模式直接与固定值匹配,适用于简单的值比较场景。

常量模式:

 int Constant_Pattern_Switch(int a) 
 {
     switch (a)
     {
         case 1:
             return 1;
         case 2: 
             return 2;
         default:
             throw new ArgumentException("未知的值",nameof(a));
     }
 }

常量模式用于null值检查

void Constant_Pattern_NullCheck(object a) 
{
    if (a is null)
    {
        Console.WriteLine("a是null");
    }
    if (a is not null)
        Console.WriteLine("a不是null");
}
  • 关系模式扩展了匹配的范围,允许比较表达式与范围或条件。

关系模式:

 void Relation_Pattern_(int a)
 {
     if (a is >100)
         Console.WriteLine("优秀");
     if (a is (<= 100 and > 60))
         Console.WriteLine("合格");
 }
  • 逻辑模式则通过and、or、not等逻辑操作符,实现模式的组合匹配,极大地增强了表达能力。

逻辑模式

void PatternCombinators(int a)
{
    if (a is (> 100 and < 200) or (> 200 and < 300 and not 250)  )
    {
        Console.WriteLine("a 在100-200之间或者200-300之间并且不是250");
    }
   
}

高级模式:深入对象结构

  • 属性模式针对对象的属性或字段进行匹配,适合复杂的对象状态验证。

属性模式

 void Property_Pattern(Vector2 v) 
 {
     //如果 向量的X,Y都大于20
     if (v is { X: > 20, Y: > 20 }) 
     {
     }
     switch (v) 
     {
         //X,Y都大于100
         case { X: > 100 ,Y:>100 }:
             break;
         default:
             break;
     }
 }
class Room
{
    public Door door;
}
class Door
{
    public double width;
    public double height;
}
//属性模式的嵌套模式
void Property_Pattern(Room room) 
{
    if (room is { door: { width: > 100 } }) 
    {
        Console.WriteLine("房门宽度大于100");
    }
}
  • 位置模式通过解构表达式,直接与数据结构的组成部分匹配,是属性模式的自然延伸。

位置模式示例:

public readonly struct Vector2
{
    public int X { get; }
    public int Y { get; }

    public Vector2(int x, int y) => (X, Y) = (x, y);
    /// <summary>
    /// 解构表达式
    /// </summary>
    /// <param name="x"></param>
    /// <param name="y"></param>
    public void Deconstruct(out int x, out int y) => (x, y) = (X, Y);
}
void Location_Pattern(Vector2 v) 
{
    if (v is (1, 0))
        Console.WriteLine("水平");
    if(v is (0,1))
        Console.WriteLine("垂直");
    switch (v)
    {
        case (1, 0):
            Console.WriteLine("水平");
            break;
            case (0, 1):
            Console.WriteLine("垂直");
            break;
    }
}
  • 列表模式(C# 11新特性)能直接与数组或列表中的序列进行模式匹配,大大提升了集合处理的便利性。

列表模式示例:

void List_Pattern(object[] num) 
{
    int a = 0;
    if (num is [1, int, var third, _]) 
    {
        Console.WriteLine("第一个为整数1");
        Console.WriteLine("第二个为整数类型");
        Console.WriteLine($"第三个为{third.ToString()}");
        Console.WriteLine("第四个随便");
    }
}

PS:
1. Deconstruct 方法是解构表达式的必要方法,没有该方法以上代码会有编译错误
2.元祖类型天然支持位置模式

辅助模式:var模式、弃元模式与括号模式

  • var模式简化变量声明与赋值过程,提升代码的简洁度。

var模式示例:

void Var_Pattern(int[] a) 
{
    if (a.Length is var len)
        Console.WriteLine($"a数组长度{len}");

    switch (a.Length)
    {
        case var alen:
            Console.WriteLine($"a数组长度{alen}");
            break;
    }    

}
  • 弃元模式(_)作为通配符,匹配任意值而不分配变量,有助于忽略不必要的部分,声明模式示例中有其应用
  • 括号模式用于明确模式组合中的优先级,使逻辑更加清晰。

总结

C#的模式匹配机制是代码优化与逻辑清晰化的利器。它通过丰富的模式种类和灵活的表达形式,将原本可能繁琐的条件判断转化为简洁、直观的表达,显著提高了开发效率与代码可读性。掌握这些模式,开发者能在编写高效、易维护的C#代码时如虎添翼。

标签:Console,C#,模式,int,switch,表达式,WriteLine,解析,模式匹配
From: https://www.cnblogs.com/dianfengbaiyang/p/18224011/GentlemanlyWind

相关文章

  • python excel从第二行开始找字段
    如果你需要从Excel文件的第二行开始读取数据,并且假设第二行是列名,你可以使用skiprows参数来跳过文件的第一行。以下是如何操作的示例:pythonimportpandasaspd#读取Excel文件,跳过第一行,假设第二行是列名df=pd.read_excel('your_file.xlsx',sheet_name='Sheet1',ski......
  • [论文阅读] Aligner@ Achieving Efficient Alignment through Weak-to-Strong Correct
    Pretitle:Aligner:AchievingEfficientAlignmentthroughWeak-to-StrongCorrectionsource:Arxiv2024paper:https://arxiv.org/abs/2402.02416code:https://aligner2024.github.io/ref:https://mp.weixin.qq.com/s/O9PP4Oc_Ee3R_HxKyd31Qg关键词:LLM,align,fin......
  • 【C语言】动态内存管理
    前言为什么要有动态内存分配?可以回想一下目前为止,我们想要向内存申请一块空间存放数据,有哪些手段呢?目前我们遇到的方式主要有两种:一、创建一个变量。比如我们存放一个整型数据,就创建一个整型变量。(也就是申请4个字节)我们创建一个变量,存放了一个数据。intn=2077;二、如......
  • windows下用vmware安装的mac虚拟机更改分辨率踩坑日记
    折腾了很久,终于把mac虚拟机安装上了!首先用unlocker解锁vmware安装macos!然后从网上下载苹果系统的安装包!注意,不要dmg镜像,要cdr格式的!装好后觉得分辨率太小!想更改分辨率!于是百度!网上说的修改com.apple.Boot.plist文件根本行不通啊!苹果限制了你修改这个文件,因为新版本的系统没有......
  • 面试专区|【DevOps-96道Docker 容器高频题整理(附答案背诵版)】
    简述什么是Docker容器?Docker容器是一个开源的应用容器引擎,它让开发者可以将他们的应用以及依赖包打包到一个可移植的容器中,然后发布到任何安装了Docker引擎的服务器上,包括流行的Linux机器、Windows机器等。Docker容器利用沙箱机制,使容器之间相互独立,互不影响。Docker容......
  • 面试专区|【69道Elasticsearch高频题整理(附答案背诵版)】
    简述什么是Elasticsearch?Elasticsearch是一个基于Lucene的搜索服务器,它提供了一个分布式、多用户能力的全文搜索引擎,基于RESTfulweb接口。Elasticsearch是用Java语言开发的,并作为Apache许可条款下的开放源码发布,是一种流行的企业级搜索引擎。它用于云计算中,能够达到实时......
  • 学生HTML个人网页作业作品 使用HTML+CSS+JavaScript个人介绍博客网站 web前端课程设计
    ......
  • U盘安装mac系统
    https://sysin.org/blog/macOS-Monterey/  1、一台Mac电脑 2、一个U盘(容量不小于8GB) 3、最新的Mac系统安装文件(可在AppStore下载)步骤:1、准备U盘:首先,将U盘插入Mac电脑的USB接口。请注意,插入U盘前确保其中没有重要数据,因为重装系统会将U盘上的所有数据清空。 2、格式......
  • m1安装cocoapods
    m1安装cocoapodshttp://www.taodudu.cc/news/show-5551017.html?action=onClick podsearchAFNetworking[!]Unabletofindapodwithname,author,summary,ordescriptionmatching`AFNetworking`podrepo返回也是0repo解决方法使用国内清华cocoapod源手动下载......
  • ABC 354
    B-AtCoderJanken2本来想开\(\rmvector<pair<string,int>>\)的,但发现其实没有必要,整数部分只需求和即可。另外,多个字符串按字典序升序排序可以直接存\(\rmvector\)后\(\rmsort\)。#include<bits/stdc++.h>usingnamespacestd;usingi64=longlong;intmai......