C# 模式匹配(一)

一、简介

模式匹配是 C# 中的一种强大功能,用于简化类型检查、条件判断和数据结构解析的代码编写。自 C# 7.0 引入以来,模式匹配的功能不断扩展,已经成为语言核心特性之一。它通过直观的语法将复杂的逻辑处理浓缩为清晰易读的表达式和结构,从而提高代码的可维护性和开发效率。

模式匹配的核心思想是根据值或数据结构的特性,直接匹配特定的模式并对其进行处理。它支持的功能包括:

1.类型模式
检查值是否为某种特定类型,并将其转换为该类型,以便进一步使用。这是最早引入的模式匹配形式,用于减少类型检查和类型转换的冗余代码。

2.常量模式
匹配具体的常量值,用于处理固定条件的判断,例如判断变量是否等于特定值。

3.属性模式
通过检查对象的属性值进行模式匹配,使得处理嵌套对象结构时更加直观。

4.位置模式
支持对元组和记录类型的解构和匹配,可以根据对象的结构直接获取相关值。

5.逻辑模式
使用逻辑运算符(and、or、not)组合多个模式条件,实现复杂的匹配逻辑。

6.列表模式
匹配数组或集合的特定结构,例如检查集合的长度、首尾元素或某些元素的模式。

7.递归模式
支持嵌套对象和复杂数据结构的递归匹配,通过一层层解构和匹配实现深层次的逻辑处理。

8.切片模式(列表中的子集匹配)
在列表模式中,可以通过 .. 来匹配集合中的某部分元素,例如匹配列表的开头或结尾。

模式匹配的一个显著优势是与 switch 表达式的结合。传统的 switch 语句在 C# 中因为模式匹配功能得到了极大的增强,不再局限于简单的常量值,而可以根据对象的类型、属性甚至逻辑条件进行分支判断。

模式匹配的优点
代码简洁:通过模式匹配,可以大大减少类型检查、类型转换和条件判断的代码量。
可读性强:模式匹配的表达形式贴近自然语言,使得代码逻辑一目了然。
灵活性高:支持复杂的逻辑组合、递归解析和数据结构解构,适用于多种场景。
类型安全:编译器会对模式匹配的代码进行类型检查,从而减少运行时错误的可能性。


应用场景
处理复杂数据结构:模式匹配在解析嵌套的 JSON、XML 等数据格式时非常有用。
对象类型判断:根据对象的不同类型执行不同的逻辑。
函数式编程:通过 switch 表达式和逻辑模式模拟函数式编程中的模式匹配能力。
条件简化:将冗长的 if-else 语句转化为简洁的模式匹配表达式。
模式匹配已成为现代 C# 语言不可或缺的部分,并且随着语言版本的迭代不断得到增强。它不仅提供了更优雅的代码编写方式,还显著提升了开发效率和代码质量。

上面的简介是由AI生成,主要是为了提高展现量,不用管!

二、C# 7 模式匹配案例

模式匹配 在 C# 7 和 C# 12 中差别还是比较大的(C# 13 在语法上没有新的用法),所以这里都单独做一些案例。

新建一个 .Net Farmework 4.8 的控制台项目。

1.is 类型判断

is 操作符结合模式匹配可以直接判断一个对象是否为某个类型,并在匹配时将其转换为该类型,消除了手动类型转换的需要。

案例:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 模式匹配
{
    internal class Program
    {
        static void Main(string[] args)
        {
            object obj = "Hello, my dog!";
            if (obj is string str)
            {
                Console.WriteLine($"The string is: {str}");
            }
            else
            {
                Console.WriteLine("obj is not a string.");
            }

            Console.ReadKey();
        }
    }
}

运行:

这里,你可以写  if (obj is string),这句代码是判断 obj 是否是 string 类型,如果在后面加上一个变量,比如:if (obj is string str),那么就是判断 obj 是否是 string 类型,如果是的话,在 if 里面括号里,str 就可以当作变量来使用了,不用像传统的写法那样,比如下面类型转换的功能。

传统的写法:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 模式匹配
{
    internal class Program
    {
        static void Main(string[] args)
        {
            string content = "30";
            int value;
            if (int.TryParse(content, out value))
            {
                Console.WriteLine("转换成功,值是:{0}", value);
            }

            Console.ReadKey();
        }
    }
}

新的写法:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 模式匹配
{
    internal class Program
    {
        static void Main(string[] args)
        {
            string content = "30";
            if (int.TryParse(content, out int value))
            {
                Console.WriteLine("转换成功,值是:{0}", value);
            }

            Console.ReadKey();
        }
    }
}

这里虽然不是 is 的用法,但写法也大致差不多,我更推荐新的写法

在获取字典的 value,同样也可以这么写:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 模式匹配
{
    internal class Program
    {
        static void Main(string[] args)
        {
            Dictionary<string, List<int>> map = new Dictionary<string, List<int>>();
            map.Add("a", null);
            string key = "b";
            if (map.TryGetValue(key, out var list))
            {
                list = new List<int>();
                map[key] = list;
            }
            map[key].Add(1);

            Console.ReadKey();
        }
    }
}

2.switch 类型匹配

在 switch 语句中,模式匹配可以用于检查对象的类型,并且每个分支可以匹配特定类型。

案例:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 模式匹配
{
    internal class Program
    {
        static void Main(string[] args)
        {
            object obj = 42;
            switch (obj)
            {
                case int number:
                    Console.WriteLine($"It's an integer: {number}");
                    break;
                case string text:
                    Console.WriteLine($"It's a string: {text}");
                    break;
                case null:
                    Console.WriteLine("It's null.");
                    break;
                default:
                    Console.WriteLine("Unknown type.");
                    break;
            }

            Console.ReadKey();
        }
    }
}

运行:

case int number: 匹配 obj 是否是 int 类型,如果是,将其赋值给变量 number。

case string text: 匹配 obj 是否是 string 类型,如果是,将其赋值给变量 text。

case null: 匹配 obj 是否是 null。

default: 是默认分支,当所有其他分支都不匹配时执行。

3.when 条件模式

when 子句允许你在模式匹配的基础上添加额外的条件。

案例:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 模式匹配
{
    internal class Program
    {
        static void Main(string[] args)
        {
            object obj = 42;
            switch (obj)
            {
                case int number when number > 10:
                    Console.WriteLine("It's an integer greater than 10.");
                    break;
                case int number:
                    Console.WriteLine("It's an integer less than or equal to 10.");
                    break;
                case string text when text.Length > 5:
                    Console.WriteLine("It's a string with more than 5 characters.");
                    break;
                default:
                    Console.WriteLine("Unknown type or condition.");
                    break;
            }

            Console.ReadKey();
        }
    }
}

运行:

case int number when number > 10  表示 obj 是否是 int 类型,如果是 int 类型,那么就赋值给 number ,并且 number 大于 10,满足条件才会进入 case 语句的内部,否则不满足条件,继续往下面判断,其他的 case 语句如此类推,大致差不多。

除了在 switch 中,if 判断也可以采用相同的写法

代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 模式匹配
{
    internal class Program
    {
        static void Main(string[] args)
        {
            object obj = 42;
            if (obj is int number && number > 10)
            {
                Console.WriteLine($"The number {number} is greater than 10.");
            }
            else if (obj is string text && text.Length > 5)
            {
                Console.WriteLine($"The string \"{text}\" has more than 5 characters.");
            }
            else
            {
                Console.WriteLine("Condition not met.");
            }

            Console.ReadKey();
        }
    }
}

运行:

后续我把 C#9 -  C#12 中模式匹配的新变化写在另一个帖子里。

结束

如果这个帖子对你有所帮助,欢迎 关注 + 点赞 + 留言

end

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

熊思宇

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值