如何在 C# 8 中使用 模式匹配

共 4296字,需浏览 9分钟

 ·

2021-01-19 10:23


模式匹配 是在 C# 7 中引入的一个非常🐂的特性,你可以在任何类型上使用 模式匹配,甚至是自定义类型,而且在 C# 8 中得到了增强,引入了大量的新模式类型,这篇文章就来讨论如何在 C# 8 中使用模式匹配。

C# 8 中的表达式模式

在 C# 8 中有三种不同的方式来表达这种模式。

  • 位置模式

  • 属性模式

  • Tuple模式

接下来看一下这些模式的相关代码及使用场景。

位置模式

位置模式主要利用类中的 Deconstruct 方法将类中的属性解构到一些零散的变量中,然后实现这些零散变量的比较,如果有点懵的话,考虑下面的 Rectangle 类。


    public class Rectangle
    {
        public int Length { getset; }
        public int Breadth { getset; }
        public Rectangle(int x, int y) => (Length, Breadth) = (x, y);
        public void Deconstruct(out int x, out int y) => (x, y) = (Length, Breadth);
    }

接下来看一下如何在 Rectangle 上使用 位置模式。


        static void Main(string[] args)
        {
            Rectangle rectangle = new Rectangle(1010);
            var result = rectangle switch
            {
                Rectangle(00) => "The value of length and breadth is zero.",
                Rectangle(1010) => "The value of length and breadth is same – this represents a square.",
                Rectangle(105) => "The value of length is 10, breadth is 5.",
                _ => "Default."
            };
            Console.WriteLine(result);
        }

如果还是蒙的话继续看看最终生成的 IL 代码,一目了然。


private static void Main(string[] args)
{
 Rectangle rectangle = new Rectangle(1010);
 if (1 == 0)
 {
 }
 if (rectangle == null)
 {
  goto IL_0056;
 }
 rectangle.Deconstruct(out int x, out int y);
 string text;
 if (x != 0)
 {
  if (x != 10)
  {
   goto IL_0056;
  }
  if (y != 5)
  {
   if (y != 10)
   {
    goto IL_0056;
   }
   text = "The value of length and breadth is same – this represents a square.";
  }
  else
  {
   text = "The value of length is 10, breadth is 5.";
  }
 }
 else
 {
  if (y != 0)
  {
   goto IL_0056;
  }
  text = "The value of length and breadth is zero.";
 }
 goto IL_005e;
 IL_0056:
 text = "Default.";
 goto IL_005e;
 IL_005e:
 if (1 == 0)
 {
 }
 string result = text;
 Console.WriteLine(result);
}

C# 8 的 属性模式

属性模式常用于实现基于类中属性的比较,考虑下面的 Employee 类。


    public class Employee
    {
        public int Id { getset; }
        public string FirstName { getset; }
        public string LastName { getset; }
        public decimal Salary { getset; }
        public string Country { getset; }
    }

下面的代码片段展示了如何利用 属性模式 实现 employee 的个人所得税计算。


        public static decimal ComputeIncomeTax(Employee employee, decimal salary) => employee switch
        {
            { Country: "Canada" } => (salary * 21) / 100,
            { Country: "UAE" } => 0,
            { Country: "India" } => (salary * 30) / 100,
            _ => 0
        };

接下来看一下如何调用,代码如下。


        static void Main(string[] args)
        {
            Employee employee = new Employee()
            {
                Id = 1,
                FirstName = "Michael",
                LastName = "Stevens",
                Salary = 5000,
                Country = "Canada"
            };
            decimal incometax = ComputeIncomeTax
            (employee, employee.Salary);
            Console.WriteLine("The income tax is {0}", incometax);
            Console.Read();
        }

C# 8 的 tuple模式

Tuple 模式是另一种模式类型,常用于实现同一时刻对多个 input 值进行测试,下面的代码片段展示了如何使用 tuple模式。


        static void Main(string[] args)
        {
            static string GetLanguageNames(string team1, string team2) => (team1, team2) switch
            {
                ("C++""Java") => "C++ and Java.",
                ("C#""Java") => "C# and Java.",
                ("C++""C#") => "C++ and C#.",
                (_, _) => "Invalid input"
            };
            (stringstringstringstring) programmingLanguages = ("C++""Java""C#""F#");

            var language1 = programmingLanguages.Item1.ToString();
            
            var language2 = programmingLanguages.Item3.ToString();
            
            Console.WriteLine($"The languages selected are: {GetLanguageNames(language1, language2)}");
        }

C# 8 中对 模式匹配进行了若干种增强,使得代码写起来更加易读,易维护 和 更加高效,也是这么多年程序员翘首以盼的特性之一。

译文链接:https://www.infoworld.com/article/3518431/how-to-use-pattern-matching-in-csharp-80.html



往期精彩回顾




【推荐】.NET Core开发实战视频课程 ★★★

.NET Core实战项目之CMS 第一章 入门篇-开篇及总体规划

【.NET Core微服务实战-统一身份认证】开篇及目录索引

Redis基本使用及百亿数据量中的使用技巧分享(附视频地址及观看指南)

.NET Core中的一个接口多种实现的依赖注入与动态选择看这篇就够了

10个小技巧助您写出高性能的ASP.NET Core代码

用abp vNext快速开发Quartz.NET定时任务管理界面

在ASP.NET Core中创建基于Quartz.NET托管服务轻松实现作业调度

现身说法:实际业务出发分析百亿数据量下的多表查询优化

关于C#异步编程你应该了解的几点建议

C#异步编程看这篇就够了


浏览 24
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报