C# 模式匹配

C# 模式匹配

patternmatching

https://www.geeksforgeeks.org/pattern-matching-in-c-sharp/

https://www.codeproject.com/Articles/5368148/Your-Quick-Guide-to-Pattern-Matching-in-Csharp

什是模式匹配

模式匹配是一种在代码中识别和提取数据的机制。它允许您以声明式的方式检查对象的形状,而无需编写冗长的条件语句。

模式匹配的优势

  • Type-Testing 类型测试
  • Nullable-type checking 可空类型检查
  • Type casting and assignment 类型转换和分配
  • High readability 可读性高
  • Concise syntax 简洁的语法
  • Less convoluted code 代码更简洁

模式匹配的主要特性包括

  1. 类型模式:检查对象是否属于特定的类型。
  2. 属性模式:检查对象是否具有特定的属性。
  3. 位置模式:检查对象的具体结构。
  4. var 模式:将匹配的值存储在变量中以供后续使用。
  5. 恒定模式 :与常量值进行测试,常量值可以包括 intfloatcharstringbool、,用constnull声明的字段。
  6. 弃元模式:与 discard 运算符_的模式匹配,匹配任何内容,包括 null,它的用法在新的开关表达式中大放异彩,以匹配默认或否则情况。
  7. 元组模式:从位置模式的特殊派生,您可以在其中测试同一表达式中类型的多个属性。
  8. 列表模式:列表匹配模式是 C# 中模式匹配的最新补充,使用列表模式,您可以将列表或数组与一组顺序元素进行匹配。

模式匹配的主要应用场景

  1. 类型判断和转换:
    • 替代传统的 isas 操作符,提供更简洁的语法。
    • switch 语句中进行类型匹配。
  2. 属性检查:
    • 检查对象是否具有某些属性,并基于属性值采取不同的操作。
    • if 语句中进行属性模式匹配。
  3. 数据解构:
    • 对元组、记录类型等复杂数据结构进行解构,提取感兴趣的部分。
    • var 模式中使用位置模式匹配。
  4. 列表和数组处理:
    • 使用模式匹配检查列表或数组的长度和元素位置。
    • switch 语句中对列表进行模式匹配。
  5. 错误处理:
    • try-catch 语句中使用模式匹配捕获特定类型的异常。
    • switch 语句中对异常类型进行模式匹配。
  6. 领域驱动设计:
    • 使用模式匹配表达领域概念,提高代码的可读性和可维护性。
    • 在领域模型中使用模式匹配进行数据验证和转换。

示例

  1. 类型判断和转换:

    object obj = "Hello, world!";
    if (obj is string s)
    {
        Console.WriteLine(s.ToUpper()); // 输出: HELLO, WORLD!
    }
    
    switch (obj)
    {
        case string s:
            Console.WriteLine($"It's a string: {s}");
            break;
        case int i:
            Console.WriteLine($"It's an integer: {i}");
            break;
        default:
            Console.WriteLine("It's something else");
            break;
    }
    
  2. 属性检查:

    var person = new { Name = "Alice", Age = 30 };
    if (person is { Age: >= 18 })
    {
        Console.WriteLine($"{person.Name} is an adult.");
    }
    
  3. 数据解构:

    var point = (10, 20);
    if (point is (int x, int y))
    {
        Console.WriteLine($"X: {x}, Y: {y}");
    }
    
    var list = new List<int> { 1, 2, 3, 4, 5 };
    if (list is [_, _, int middle, _, _])
    {
        Console.WriteLine($"The middle element is: {middle}");
    }
    
  4. 列表和数组处理:

    var numbers = new List<int> { 1, 2, 3, 4, 5 };
    switch (numbers)
    {
        case []:
            Console.WriteLine("The list is empty.");
            break;
        case [int first]:
            Console.WriteLine($"The list has one element: {first}");
            break;
        case [int first, int second]:
            Console.WriteLine($"The list has two elements: {first}, {second}");
            break;
        case var all:
            Console.WriteLine($"The list has {all.Count} elements.");
            break;
    }
    
  5. 错误处理:

    try
    {
        // 某些可能引发异常的操作
    }
    catch (DivideByZeroException ex)
    {
        Console.WriteLine($"Caught DivideByZeroException: {ex.Message}");
    }
    catch (Exception ex)
    {
        Console.WriteLine($"Caught general Exception: {ex.Message}");
    }
    
    
  6. 领域驱动设计:

    public record Person(string Name, int Age);
    
    var person = new Person("Alice", 30);
    if (person is { Age: >= 18 })
    {
        Console.WriteLine($"{person.Name} is an adult.");
    }
    
  7. 恒定模式:

    public bool IsFreshProduce(FoodModel food)
    {
        return food?.Category?.ID is (int)  ProductCategoryEnum.FreshProduce;
    }
    
  8. 弃元模式:

    //如果未提供食物的储存温度或数字与以下范围不匹配,则将引发自定义异常
    public int GetFoodStorageTemperature
           (StorageRequirementEnum storageRequirement) => storageRequirement switch
    {
        StorageRequirementEnum.Freezer => -18,
        StorageRequirementEnum.Refrigerator => 4,
        StorageRequirementEnum.RoomTemperature => 25,
        _ => throw new InvalidStorageRequirementException()
    };
    
    // switch (storageRequirement)
            // {
            //     case StorageRequirementEnum.Freezer:
            //         return -18;
            //     case StorageRequirementEnum.Refrigerator:
            //         return 4;
            //     case StorageRequirementEnum.RoomTemperature:
            //         return 25;
            //     default:
            //         throw new Exception();
            // }
    
  9. 元组模式:

    //转基因食品检测
    public string GetFoodDescription(FoodModel food) => (food.NonGMO, food.Category.ID) switch
    {
     (true, (int)ProductCategoryEnum.FreshProduce) => "Non-GMO Fresh Product",
     (true, (int)ProductCategoryEnum.Dairy) => "Non-GMO Dairy",
     (false, (int)ProductCategoryEnum.Meats) => "GMO Meats. Avoid!",
     (_, _) => "Invalid Food Group"
    };
    // switch (food.NonGMO, food.Category.ID)
    // {
    //     case (true, (int)ProductCategoryEnum.FreshProduce):
    //         return "Non-GMO Fresh Product";
    //     case (true, (int)ProductCategoryEnum.Dairy):
    //         return "Non-GMO Dairy";
    //     case (false, (int)ProductCategoryEnum.Meats):
    //         return "GMO Meats. Avoid!";
    //     default:
    //         return "Invalid Food Group";
    // }
    
    
  10. 列表模式:

public (int?, int?) FindNumberOneAndNumberFour()
{
   int[] numbers = { 1, 2, 3, 4, 5 };
   // Match if 2nd value is anything, 3rd is greater than or equal 3, fifth is 5
   if (numbers is [var numberOne, _, >= 3, int numberFour, 5])
   {
       return (numberOne, numberFour);
   }
   return (null, null);
}

这些案例展示了模式匹配在各种场景下的应用,包括类型判断、属性检查、数据解构、列表处理、错误处理以及领域建模等。通过使用模式匹配,您可以编写更简洁、可读性更强的代码,同时也能在某些情况下提高性能。熟练掌握这些模式匹配的使用技巧,将有助于您提高代码质量和开发效率。

获得永久免费的无限 GPT 查询次数,点击链接并下载Monica插件,即可参加限时活动。
https://monica.im/invitation?c=OWBJ2ZBE

posted @ 2024-06-18 17:54  世纪末の魔术师  阅读(163)  评论(0编辑  收藏  举报
  1. 1 ありがとう··· KOKIA
ありがとう··· - KOKIA
00:00 / 00:00
An audio error has occurred.

作词 : KOKIA

作曲 : KOKIA

编曲 : 日向敏文

作词 : KOKIA

作曲 : KOKIA

誰もが気付かぬうちに

誰もが気付かぬうちに

何かを失っている

フッと気付けばあなたはいない

思い出だけを残して

せわしい時の中

言葉を失った人形達のように

街角に溢れたノラネコのように

声にならない叫びが聞こえてくる

もしも もう一度あなたに会えるなら

もしも もう一度あなたに会えるなら

たった一言伝えたい

ありがとう

ありがとう

時には傷つけあっても

時には傷つけあっても

あなたを感じていたい

思い出はせめてもの慰め

いつまでもあなたはここにいる

もしも もう一度あなたに会えるなら

もしも もう一度あなたに会えるなら

たった一言伝えたい

ありがとう

ありがとう

もしも もう一度あなたに会えるなら

もしも もう一度あなたに会えるなら

たった一言伝えたい

もしも もう一度あなたに会えるなら

たった一言伝えたい

ありがとう

ありがとう

時には傷つけあっても

時には傷つけあっても

あなたを感じてたい