5

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

 3 years ago
source link: https://mp.weixin.qq.com/s?__biz=MzU4Mjc4NzgyOQ%3D%3D&%3Bmid=2247488238&%3Bidx=1&%3Bsn=70059391ca0ad5686df36533fd9bda65
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

IjEvUn6.gif!mobile

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

C# 8 中的表达式模式

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

  • 位置模式

  • 属性模式

  • Tuple模式

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

位置模式

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


public class Rectangle
{
public int Length { get; set; }
public int Breadth { get; set; }
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(10, 10);
var result = rectangle switch
{
Rectangle(0, 0) => "The value of length and breadth is zero.",
Rectangle(10, 10) => "The value of length and breadth is same – this represents a square.",
Rectangle(10, 5) => "The value of length is 10, breadth is 5.",
_ => "Default."
};
Console.WriteLine(result);
}

zAJVNrM.png!mobile

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


private static void Main(string[] args)
{
Rectangle rectangle = new Rectangle(10, 10);
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 { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public decimal Salary { get; set; }
public string Country { get; set; }
}

下面的代码片段展示了如何利用 属性模式 实现 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();
}

ZviyQz3.png!mobile

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"
};
(string, string, string, string) programmingLanguages = ("C++", "Java", "C#", "F#");

var language1 = programmingLanguages.Item1.ToString();

var language2 = programmingLanguages.Item3.ToString();

Console.WriteLine($"The languages selected are: {GetLanguageNames(language1, language2)}");
}

aIzeaqJ.png!mobile

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

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

B7nYBzr.jpg!mobile

往期 精彩 回顾

【推荐】.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#异步编程看这篇就够了


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK