• C# 使用模式匹配的好处,因为好用所以推荐~


    1. 类型检查和转换:当你需要检查对象是否为特定类型,并且希望在同一时间内将其转换为那个类型时,模式匹配提供了一种更简洁的方式来完成这一任务,避免了使用传统的as和is操作符后还需要进行额外的null检查。

    2. 复杂条件逻辑:在处理复杂的条件逻辑时,特别是涉及到多个条件和类型的情况下,使用模式匹配可以使代码更加清晰易读。通过模式匹配,可以将复杂的if-else链或switch语句简化,使逻辑更直观。

    3. 解构复合类型:当你需要从复合类型(如元组、自定义类等)中提取值时,模式匹配允许你直接在条件检查中进行解构,这样可以避免编写额外的解构代码,使得代码更加简洁。

    4. 范围检查:对于需要进行范围检查的场景,如检查一个数是否落在某个区间内,使用C# 9.0引入的关系模式可以极大简化代码,使得范围检查逻辑一目了然。

    5. 逻辑组合:在需要对多个条件进行逻辑组合的情况下,如需要检查一个值是否满足多个条件之一或全部条件,使用逻辑模式可以直接在模式匹配表达式中使用and、or和not运算符,避免了复杂的逻辑嵌套。

    6. 数据验证:模式匹配可以用于数据验证场景,特别是当验证逻辑涉及到类型检查、值范围检查或特定属性值检查时。通过模式匹配,可以在单个表达式中完成所有这些检查,使得验证逻辑更加紧凑和易于维护。

    7. 多态行为:在处理需要根据对象类型执行不同操作的多态行为时,模式匹配提供了一种更灵活的方式来替代传统的虚方法或接口实现。这使得在不修改原有类层次结构的情况下,能够更容易地扩展或修改行为。

    8. 替代访问者模式:在实现访问者设计模式时,模式匹配可以作为一种更简洁的替代方案,特别是在处理复杂的对象结构时。通过模式匹配,可以直接在一个地方处理所有类型的情况,而不需要为每种类型创建单独的访问者方法。

    模式匹配的这些用途展示了它在简化代码、提高可读性和灵活处理不同类型和条件的强大能力。随着C#语言的发展,模式匹配的功能和应用场景将会进一步扩展和深化。

    下面我们看下一些经典的模式匹配编码风格:

    is断言 变量str已被安全地转换为string类型

    object obj = "Hello, World!";
    if (obj is string str) {
        Console.WriteLine(str);
    }
    

    is对可空类型的断言

    public record Person(int Id, string? Name, bool? IsActived);
    var person = new Person(1, "vipwan", null);
    if (person?.IsActived is true)
    {
        Console.WriteLine($"Id {person.Id} 已激活");
    }
    

    switch 允许使用多种模式,包括类型模式、常量模式和var模式 ,无需我们提前做转换以节省编码量

    var obj = 0;
    switch (obj)
    {
        case 0:
            Console.WriteLine("Zero");
            break;
        case var value when value > 100:
            Console.WriteLine($"Value: {value}>100");
            break;
        default:
            Console.WriteLine($"Value: {obj}");
            break;
    }
    

    switch 中使用弃元_代替变量

    public static string CronEveryNHours(this int n) => n switch
    {
    	(>= 1 and < 24) => $"0 0/{n} * * *",
    	_ => throw new ArgumentException("n must be between 1 and 24", nameof(n))
    };
    

    switch 自由组合模式,允许你组合多个条件因子判断逻辑,这对于复杂的逻辑判断相当有用

    [Theory]
    [InlineData(18, "vipwan", "shanghai", "true")]
    [InlineData(20, "", "", "adult")]
    [InlineData(70, "vipwan", "", "old")]
    [InlineData(90, "vipwan", "shanghai", "shanghai")]
    public void Test(int age, string username, string address, string result) {
      var real = (age, username, address) switch {
         (18, "vipwan", "shanghai") => "true",
         ( > 18 and < 60, _, _) => "adult",
         (_, _, "shanghai") => "shanghai",
         ( > 60, _, _) => "old",
         _ => "unknown"
      };
      Assert.Equal(result, real);
    }
    

    C# 8.0引入了属性模式,允许基于对象的属性进行模式匹配

    public record Person(string Name,int Age);
    var person = new Person("vipwan", 30);
    //通俗易懂:如果person不为null,且name==vipwan 并且age>=18的时候
    if (person is { Name: "vipwan", Age: >= 18 }) {
        Console.WriteLine("vipwan is an adult.");
    }
    

    C# 9.0引入的逻辑模式,它允许使用逻辑运算符andornot来组合模式。

    if (number is > 0 and < 10 or 100) {
        Console.WriteLine("Number is between 0 and 10 or equals 100.");
    }
    

    元组模式允许你对元组的元素进行模式匹配,这在处理元组返回值或多值情况时非常有用

    var numbers = (1, "one", 18);
    if (numbers is (1, string name, int age)) {
        Console.WriteLine($"The name of 1 is {name}, age {age}!");
    }
    

    列表模式允许对数组、列表等集合进行模式匹配,可以匹配集合的长度、元素等属性。这对于处理集合数据时进行模式匹配提供了极大的便利。

    int[] numbers = { 1, 2, 3 };
    if (numbers is [1, 2, 3]) {
        Console.WriteLine("The array contains the numbers 1, 2, and 3 in that order.");
    }
    

    切片模式允许你匹配集合的一部分,而不是整个集合。这在你只关心集合的某个特定部分时特别有用。

    int[] numbers = { 0, 1, 2, 3, 4 };
    if (numbers is [0, .., 4]) {
        Console.WriteLine("The array starts with 0 and ends with 4.");
    }
    

    这里只是介绍了部分好用常见的模式匹配,随着C#语言的逐代增强,可能会有更多的新特性和改进被引入。

  • 相关阅读:
    入职前学习SystemVerilog
    PHP正则表达式(匹配手机号码、邮箱、img中的src值)
    来了!Linkflow率先对接『有赞黑金版』,全面赋能品牌精细化运营!
    使用Python获取文件中的字符数、单词数、空格数和行数
    Javascript中扩展运算符的作用及使用场景
    论道金陵 | 原生数字浪潮来袭,如何乘势而上?
    Python面向对象三大特征
    iPayLinks艾贝盈上线澳大利亚、印尼本地收款账户,助力企业紧抓RCEP机遇
    2.15-CSS基础--vertical-align垂直对齐、光标类型、边框圆角
    Vue计算属性computed,全选反选案例
  • 原文地址:https://www.cnblogs.com/vipwan/p/18309290