如何在 C# 8 中使用 模式匹配
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.
模式匹配
是在 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);
}
如果还是蒙的话继续看看最终生成的 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();
}
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)}");
}
C# 8 中对 模式匹配进行了若干种增强,使得代码写起来更加易读,易维护 和 更加高效,也是这么多年程序员翘首以盼的特性之一。
译文链接:https://www.infoworld.com/article/3518431/how-to-use-pattern-matching-in-csharp-80.html
往期 精彩 回顾
.NET Core实战项目之CMS 第一章 入门篇-开篇及总体规划
【.NET Core微服务实战-统一身份认证】开篇及目录索引
Redis基本使用及百亿数据量中的使用技巧分享(附视频地址及观看指南)
.NET Core中的一个接口多种实现的依赖注入与动态选择看这篇就够了
用abp vNext快速开发Quartz.NET定时任务管理界面
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK