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

模式匹配 是在 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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章