模式匹配
是在 C# 7 中引入的一個非常????的特性,你可以在任何類型上使用 模式匹配
,甚至是自定義類型,而且在 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