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

更多高质量干货:参见我的 GitHub: csharptranslate