概述
C# 12 为其已经强大的模式匹配功能引入了令人兴奋的新特性。这些增强功能为开发者提供了更具表现力和简洁的方式来处理数据,从而带来更干净、更易维护的代码。在本文中,我们将讨论 C# 12 的两大增强功能:let
模式和高级递归模式。为了充分利用这些模式,我们将解释它们的工作原理及优势,并提供实用的代码示例。
什么是 C# 中的模式匹配?
C# 中的模式匹配功能允许你以清晰简洁的方式将值与特定模式进行比较,并从中提取数据。从 C# 7 引入并在后续版本中扩展,模式匹配使处理复杂数据结构和 switch
表达式变得更加容易。
C# 12 的模式匹配工具包增强了以下内容:
let
模式:通过let
模式引入中间变量。递归模式:递归模式允许匹配和解构更复杂的嵌套对象。
让我们深入了解每个特性。
C# 12 的 let
模式
C# 12 的一个突出特性是 let
模式,它允许你在模式匹配中定义并绑定一个变量,并在后续重用该值。当你想要重用表达式的结果或涉及复杂条件时,这尤其有用。
基本 let
模式的代码示例
namespace CSharp12.AdvancedPatternMatching;
public static class SimpleLetPattern
{
public static string CheckDiscount(int age)
{
return age switch
{
// 使用 'let' 引入中间变量
let isAdult when isAdult >= 18 => "Eligible for discount",
_ => "Not eligible for discount"
};
}
}
在这里,我们引入了 isAdult
变量,包含 age
值。条件 isAdult >= 18
在模式内部评估,如果年龄大于等于 18,则返回 "Eligible for discount"(有资格享受折扣)。
let
模式的优势
可读性:将复杂的条件简化为可管理的块。 重用性:多个检查可以重用已计算的值,减少冗余。 中间计算:模式中的计算可以作为中间计算被后续检查重用。
C# 12 递归模式
位置模式和属性模式允许在嵌套数据结构(如复杂对象或元组)中进行深度解构和匹配。
使用元组的递归模式代码示例
下面是递归匹配元组的简单示例:
namespace CSharp12.AdvancedPatternMatching;
public static class SimpleLetPattern
{
public static string GetCoordinates((int X, int Y) point)
{
return point switch
{
// 递归模式匹配元组
(0, 0) => "Origin",
(let x, 0) when x > 0 => "X-axis positive",
(0, let y) when y > 0 => "Y-axis positive",
_ => "Somewhere else"
};
}
}
在此示例中,元组 (int X, int Y)
的元素被递归匹配:
值 (0, 0)
对应于原点,当 x > 0
时,匹配任何 X 轴正侧的点(let x, 0)
,(0, let y)
对应于任何 Y 轴正侧的点当y > 0
时。
使用 let
模式,你可以轻松地将元组的部分分配给变量并应用进一步的条件。
对象递归模式的代码示例
假设你有嵌套的类或记录,并且需要对深层嵌套的属性进行模式匹配:
namespace CSharp12.AdvancedPatternMatching;
public class Address
{
public string City { get; set; }=string.Empty;
public string Country { get; set; } = string.Empty;
}
namespace CSharp12.AdvancedPatternMatching;
public class Person
{
public string Name { get; set; }=string.Empty;
public Address? Address { get; set; }
public static string GetPersonLocation(Person person)
{
return person switch
{
// 对嵌套对象进行递归模式匹配
{ Address: { City: "New York", Country: "USA" } } => "Person is in New York, USA",
{ Address: { Country: "USA" } } => "Person is in the USA",
{ Address: { City: var city } } => $"Person is in {city}",
_ => "Location unknown"
};
}
}
在这个例子中,我们对 Person
对象的嵌套 Address
属性进行递归匹配:
如果人位于纽约,则返回特定信息。 如果人位于美国任何地方,则返回一般信息。 如果只知道城市,则输出城市名称。
带解构的高级递归模式
你还可以将递归模式与解构结合使用,这在处理元组和记录时特别有用。
namespace CSharp12.AdvancedPatternMatching;
public record Point(int X, int Y);
public static class Points
{
public static string DescribePoint(Point point)
{
return point switch
{
// 使用解构进行递归匹配
Point(0, 0) => "At the origin",
Point(let x, let y) when x == y => "X equals Y",
Point(let x, _) when x > 0 => "Positive X-coordinate",
Point(_, let y) when y > 0 => "Positive Y-coordinate",
_ => "Somewhere else"
};
}
}
Point
记录可以解构为其组件 X
和 Y
,如下所示:
如果两者均为零,则返回 "At the origin"。 如果 X == Y
,则返回 "X equals Y"。相应地,如果 X
或Y
为正数,则提供具体信息。
使用 let
和递归模式
在 C# 12 中,你可以将 let
模式与递归模式结合使用,创建更具表现力和功能强大的代码。
复杂递归模式与 let
的代码示例
namespace CSharp12.AdvancedPatternMatching;
public class TreeNode
{
public int Value { get; set; }
public TreeNode Left { get; set; }
public TreeNode Right { get; set; }
public static string SearchTree(TreeNode node)
{
return node switch
{
// 使用 let 捕获节点值
{ Value: let value, Left: null, Right: null } => $"Leaf node with value {value}",
{ Left: { Value: let leftValue } } when leftValue > 0 => "Left child is positive",
{ Right: { Value: let rightValue } } when rightValue < 0 => "Right child is negative",
_ => "Other node"
};
}
}
此示例使用 let
模式捕获当前节点及其子节点的值。你可以根据这些值应用条件,这在树状数据结构中特别有用。
总结
C# 12 中的高级模式匹配功能为开发者提供了强大的工具,包括 let
模式和增强的递归模式。使用这些模式,你可以编写简洁的声明性逻辑,能够更具表现力地处理复杂条件和深度嵌套的数据,同时提高代码的可读性和维护性。
无论你是在处理简单数据结构还是复杂的递归数据,集成这些高级模式匹配技术到你的项目中,将提升开发体验,并提高应用程序的质量。
通过使用这些高级模式匹配功能,我们的 C# 代码将变得更具表现力,更易于阅读和维护。
译文地址:c-sharpcorner.com/article/an-in-depth-look-at-advanced-pattern-matching-in-c-sharp-12/
作者:Ziggy Rafiq
关注公众号↑↑↑:DotNet开发跳槽❀