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

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

[[376473]]

本文转载自微信公众号「码农读书」,作者码农读书 。转载本文请联系码农读书公众号。

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

C# 8 中的表达式模式

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

  • 位置模式
  • 属性模式
  • Tuple模式

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

位置模式

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

  1. public class Rectangle 
  2.    { 
  3.        public int Length { get; set; } 
  4.        public int Breadth { get; set; } 
  5.        public Rectangle(int x, int y) => (Length, Breadth) = (x, y); 
  6.        public void Deconstruct(out int x, out int y) => (x, y) = (Length, Breadth); 
  7.    } 

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

  1. static void Main(string[] args) 
  2.         { 
  3.             Rectangle rectangle = new Rectangle(10, 10); 
  4.             var result = rectangle switch 
  5.             { 
  6.                 Rectangle(0, 0) => "The value of length and breadth is zero."
  7.                 Rectangle(10, 10) => "The value of length and breadth is same – this represents a square."
  8.                 Rectangle(10, 5) => "The value of length is 10, breadth is 5."
  9.                 _ => "Default." 
  10.             }; 
  11.             Console.WriteLine(result); 
  12.         } 

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

  1. private static void Main(string[] args) 
  2.  Rectangle rectangle = new Rectangle(10, 10); 
  3.  if (1 == 0) 
  4.  { 
  5.  } 
  6.  if (rectangle == null
  7.  { 
  8.   goto IL_0056; 
  9.  } 
  10.  rectangle.Deconstruct(out int x, out int y); 
  11.  string text; 
  12.  if (x != 0) 
  13.  { 
  14.   if (x != 10) 
  15.   { 
  16.    goto IL_0056; 
  17.   } 
  18.   if (y != 5) 
  19.   { 
  20.    if (y != 10) 
  21.    { 
  22.     goto IL_0056; 
  23.    } 
  24.    text = "The value of length and breadth is same – this represents a square."
  25.   } 
  26.   else 
  27.   { 
  28.    text = "The value of length is 10, breadth is 5."
  29.   } 
  30.  } 
  31.  else 
  32.  { 
  33.   if (y != 0) 
  34.   { 
  35.    goto IL_0056; 
  36.   } 
  37.   text = "The value of length and breadth is zero."
  38.  } 
  39.  goto IL_005e; 
  40.  IL_0056: 
  41.  text = "Default."
  42.  goto IL_005e; 
  43.  IL_005e: 
  44.  if (1 == 0) 
  45.  { 
  46.  } 
  47.  string result = text; 
  48.  Console.WriteLine(result); 

C# 8 的 属性模式

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

  1. public class Employee 
  2.     { 
  3.         public int Id { get; set; } 
  4.         public string FirstName { get; set; } 
  5.         public string LastName { get; set; } 
  6.         public decimal Salary { get; set; } 
  7.         public string Country { get; set; } 
  8.     } 

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

  1. public static decimal ComputeIncomeTax(Employee employee, decimal salary) => employee switch 
  2.         { 
  3.             { Country: "Canada" } => (salary * 21) / 100, 
  4.             { Country: "UAE" } => 0, 
  5.             { Country: "India" } => (salary * 30) / 100, 
  6.             _ => 0 
  7.         }; 

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

  1. static void Main(string[] args) 
  2.         { 
  3.             Employee employee = new Employee() 
  4.             { 
  5.                 Id = 1, 
  6.                 FirstName = "Michael"
  7.                 LastName = "Stevens"
  8.                 Salary = 5000, 
  9.                 Country = "Canada" 
  10.             }; 
  11.             decimal incometax = ComputeIncomeTax 
  12.             (employee, employee.Salary); 
  13.             Console.WriteLine("The income tax is {0}", incometax); 
  14.             Console.Read(); 
  15.         } 

C# 8 的 tuple模式

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

  1. static void Main(string[] args) 
  2.         { 
  3.             static string GetLanguageNames(string team1, string team2) => (team1, team2) switch 
  4.             { 
  5.                 ("C++""Java") => "C++ and Java."
  6.                 ("C#""Java") => "C# and Java."
  7.                 ("C++""C#") => "C++ and C#."
  8.                 (_, _) => "Invalid input" 
  9.             }; 
  10.             (string, string, string, string) programmingLanguages = ("C++""Java""C#""F#"); 
  11.  
  12.             var language1 = programmingLanguages.Item1.ToString(); 
  13.              
  14.             var language2 = programmingLanguages.Item3.ToString(); 
  15.              
  16.             Console.WriteLine($"The languages selected are: {GetLanguageNames(language1, language2)}"); 
  17.         } 

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

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

 

责任编辑:武晓燕 来源: 码农读书
相关推荐

2021-02-01 12:36:59

C# Channels存储

2021-01-19 05:30:55

C# 8异步流IEnumerable

2021-01-28 05:14:40

C#接口签名

2021-01-22 05:53:08

C# IndexRange

2020-12-31 07:31:10

C# 反射数据

2021-03-07 16:37:52

C#应用程序

2018-08-03 08:37:31

设计模式IT项目GDPR

2021-11-25 00:04:16

C# 插值字符串

2009-08-04 10:29:06

在C#中使用存储过程

2020-01-07 09:50:41

Windows 10上帝模式Windows

2009-08-31 16:12:02

C#使用Singlet

2020-11-30 11:55:07

Docker命令Linux

2019-09-16 19:00:48

Linux变量

2014-07-02 09:47:06

SwiftCocoaPods

2024-09-06 11:34:15

RustAI语言

2020-04-09 10:18:51

Bash循环Linux

2021-03-09 07:27:40

Kafka开源分布式

2022-05-17 08:25:10

TypeScript接口前端

2022-06-23 08:00:53

PythonDateTime模块

2021-06-09 09:36:18

DjangoElasticSearLinux
点赞
收藏

51CTO技术栈公众号