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

模式匹配是编程领域中一种强大的工具,用于检测表达式是否符合特定条件,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#代码时如虎添翼。

posted @   巅峰白杨  阅读(91)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 实操Deepseek接入个人知识库
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
点击右上角即可分享
微信分享提示