C#知识学习-007(​​模式匹配)

1.模式匹配是什么

“模式匹配”是一种测试表达式是否具有特定特征的方法。

简单说,就是​​检查一个数据“长什么样”或“是什么”​​,然后根据这个“样子”决定程序做什么。

C# 支持多种模式,常用的大概有:

声明模式:检查表达式的运行时类型,如果匹配成功,请将表达式结果分配给声明的变量。
类型模式:检查表达式的运行时类型。
常量模式:测试表达式结果是否等于指定的常量。
关系模式:将表达式结果与指定的常量进行比较。
逻辑模式:测试表达式是否与模式的逻辑组合匹配。
弃元模式:匹配任何表达式。

(注:不用担心,我会在后面的例子中举例说明并标注)

2.Null检查

​类型名称后添加 ? 符号​​表示该类型​​允许值为 null​(空值),这是一个可空类型(Nullable Type)的语法。

标准类型 vs 可空类型​​:

  • 普通 bool 类型只能有两个值:true 或 false
  • bool? 类型允许三个值:​truefalse 或 null​。

举个例子看看:

bool? isActive = null; // 合法,因为 bool? 允许 null
bool normalBool = null; // 编译错误!普通 bool 不能为 null

// 使用场景:检查记录是否存在
bool? hasPermission = 某一个值;//某一个值可能为true或null 
if (hasPermission == true) 
{
    Console.WriteLine("yes");
} 
else if (hasPermission == null) 
{
    Console.WriteLine("get null");
}

注意:直接使用可空类型前需检查是否为 null,我来举例

int? nullableInt = 某一个值; // 某一个值可能是 具体的int值 或 null

// 正确:先检查是否为 null
if (nullableInt.HasValue) 
{
    // 安全访问真实值
    int actualValue = nullableInt.Value; 
    Console.WriteLine($"num is {actualValue}");
}
else
{
    Console.WriteLine("num is null");
}

3.模式匹配怎么用

🎯 你只需要掌握两种用法:

3.1 is表达式(单个检查)

“is 表达式”支持通过模式匹配来测试表达式,并根据测试结果有条件地声明一个新的变量。

目的​​:检查表达式的类型/结构,匹配成功时​​同时声明一个新变量​​。

✅ ​​核心优势:检查类型的同时直接生成变量!​

is 表达式的结构​​:

if (变量 is 类型 新变量名)

模式匹配最常见的方案之一是确保值不是 null

int? maybe = 12;
if (maybe is int number)
{
    Console.WriteLine($"The int 'maybe' has the value {number}");
}
else
{
    Console.WriteLine("The int 'maybe' doesn't hold a value");
}

注:

maybe is int 检查运行时 maybe 的实际类型是否为 int(类型模式的体现

.... is int number 声明并初始化新变量 number (​​声明模式的体现

双重功能​​:

  • 先执行​​类型检查​​(类型模式)
  • 成功后执行​​变量声明与赋值​​(声明模式)

模式匹配的另一种常见用途是测试变量是否与给定类型匹配。 举一个例子吧:

void CheckType(object obj)
{
    // 使用is表达式进行类型检查
    if (obj is int number)
    {
        Console.WriteLine($"this is a int: {number} (and: {number * number})");
    }
    else if (obj is string text)
    {
        Console.WriteLine($"this is a string: \"{text}\" (and: {text.Length})");
    }
    else if (obj is double decimalNumber)
    {
        Console.WriteLine($"this is a double: {decimalNumber} (and: {decimalNumber * 2})");
    }
    else
    {
        Console.WriteLine($"what: {obj.GetType().Name}");
    }
}

// 测试不同的对象
CheckType(42);           // 整数
CheckType("Hello World");// 字符串
CheckType(3.14);         // 浮点数
CheckType(true);         // 布尔值
CheckType(new object()); // 普通对象

补充: 为什么用 object 类型?

在 C# 中,object 是所有类型的基类,也就是:

int number = 42;          // 值类型
string text = "Hello";    // 引用类型

// 所有类型都能赋值给object
object obj1 = number;
object obj2 = text;   

3.2 switch表达式(多个检查)

“switch 表达式”允许你根据表达式的首次匹配模式执行操作。

目的​​:针对一个输入值,测试多种可能的模式并​​直接返回一个结果​​。

switch表达式的结构:

结果变量 = 输入值 switch
{
    匹配模式1 => 结果值1,
    匹配模式2 => 结果值2,
    匹配模式3 => 结果值3,
    _ => 默认结果值 // 必须包含的默认分支
};

工作原理:当执行switch表达式时

  1. 程序会从上到下依次检查每个分支
  2. 当找到第一个匹配的分支时,立即执行并返回对应的结果值
  3. 如果没有任何分支匹配,则执行默认分支(_)
  4. 返回的结果值被赋给左侧的结果变量

举一个使用常量模式的例子:

void HandleTrafficSignal(string? signal)
{
    string action = signal switch
    {
        "Red" => "Stop",
        "Yellow" => "wait",
        "Green" => "gogogo",
        null => "what",
        _ => "Unknown signal"
    };

    Console.WriteLine($"Signal: {signal} → Action: {action}");
}

// 测试
HandleTrafficSignal("Red");
HandleTrafficSignal("Green");
HandleTrafficSignal(null);
HandleTrafficSignal("Flashing");

注:

"Red" => "Stop"  精确匹配特定字符串值(​​常量模式的体现

_ => "Unknown signal"  默认处理所有未匹配的情况 (​​弃元模式的体现

再举一个例子吧:

void PrintResult(int score)
{
    // Switch表达式判断分数等级
    string grade = score switch
    {
        < 50 => "Fail",
        >= 50 and < 90 => "Pass",
        >= 90 and <= 100 => "Distinction",
        _ => "Invalid Score"
    };

    Console.WriteLine($"Score: {score} - {grade}");
}

//测试
PrintResult(25);
PrintResult(55);
PrintResult(95);
PrintResult(105);

注:

< 50 => "Fail"  直接使用比较运算符进行值范围匹配(​关系模式的体现

>= 50 and < 90  使用逻辑运算符 and 组合多个条件 (逻辑模式的体现

_ => "Invalid Score"   表示"其他所有情况"(弃元模式的体现

✅ ​​核心优势:​

  1. ​直接返回结果​​(不用先声明变量)
  2. ​强制处理所有情况​​(忘写default会编译报错!)

4.枚举匹配

4.1 枚举

枚举(Enum)是一种值类型,它用于定义一组命名的整数常量。

默认情况下,枚举中的第一个元素的值是0,后面的元素依次增加1。

用星期来举例:

enum DaysOfWeek
{
    Monday,    // 默认值为0
    Tuesday,   // 1
    Wednesday, // 2
    Thursday,  // 3
    Friday,    // 4
    Saturday,  // 5
    Sunday     // 6
}

当然也可以指定值:

enum StatusCode
{
    OK = 200,
    NotFound = 404,
    ServerError = 500
}

4.2 枚举匹配使用

举个例子:现在有一个信息等级的枚举

LogLevel log = LogLevel.Warning;
enum LogLevel 
{ 
    Info, 
    Warning,
    Error 
}

先来看看如果使用传统的switch 语句

switch (log)
{
    case LogLevel.Info:
        Console.WriteLine("Info123");
        break;
    case LogLevel.Warning:
        Console.WriteLine("Warning123");
        break;
    case LogLevel.Error:
        Console.WriteLine("Error123");
        break;
}

现在使用Switch 表达式:

string message = log switch
{
    LogLevel.Info => "Info123",
    LogLevel.Warning => "Warning123",
    LogLevel.Error => "Error123",
    _ => "Unknown" // 默认处理
};

现在来深入对比一下:

特性Switch 表达式传统 Switch 语句
​目的​返回值 (表达式角色)执行操作 (语句角色)
​默认处理​必须包含 _ 分支可省略 default
​case 语法​直接 成员 => 值case 成员: 语句块
​break/return​不需要必须显式使用

总结:

优先使用 Switch 表达式​​:当需要基于枚举值返回结果时,更简洁安全

传统语句适用场景​​:

        需要执行多个独立操作的复杂逻辑;

        面向早期 C# 版本的项目(< 8.0);

        已有复杂 switch 语句需要维护

学到了这里,咱俩真棒,记得按时吃饭(祝你立秋快乐噢!)

【本篇结束,新的知识会不定时补充】

感谢你的阅读!如果内容有帮助,欢迎 ​​点赞❤️ + 收藏⭐ + 关注​​ 支持! 😊

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值