C# Pattern Matching 基础教程 – wiki基地


C# Pattern Matching 基础教程:解锁现代 C# 的强大特性

C# 作为一门成熟且不断发展的编程语言,在近年来的版本迭代中引入了许多令人兴奋的特性,其中模式匹配 (Pattern Matching) 无疑是最具影响力和实用性的增强之一。它并非一个单一的功能,而是一系列语言结构的集合,旨在简化代码中常见的、基于数据“形状”或“类型”进行判断和提取值的逻辑。模式匹配显著提高了代码的可读性、简洁性和表达力,尤其是在处理复杂的数据结构和条件逻辑时。

本教程将深入探讨 C# 模式匹配的基础知识,从基本概念入手,逐步介绍各种模式类型及其在 is 操作符和 switch 语句/表达式中的应用。我们将通过丰富的代码示例,帮助您理解并掌握这一现代 C# 的核心特性。

什么是模式匹配?

在编程中,“模式”可以理解为一种用于测试数据是否具有特定“结构”或“属性”的规则。模式匹配则是将输入数据与这些模式进行比较的过程。如果数据符合某个模式,匹配成功,并且通常可以方便地从数据中提取出感兴趣的部分。

在 C# 出现模式匹配之前,我们通常需要依赖一连串的 if-else if 语句、类型转换(as 或强制转换)以及空值检查来完成类似的任务。这种方式往往导致代码冗长、嵌套层级深,且容易出错。

C# 模式匹配通过引入新的语法糖和扩展现有结构(如 isswitch),提供了一种更声明式、更类型安全、更简洁的方式来表达这些逻辑。

模式匹配的演进

模式匹配并非一蹴而就,而是随着 C# 版本的更新逐步增强的:

  • C# 7.0: 引入了模式匹配的基础,主要包括 is 操作符的类型模式 (Type Pattern) 和 switch 语句中的 case 类型模式以及 when 子句。
  • C# 8.0: 带来了革命性的 switch 表达式,以及更多的模式类型,如属性模式 (Property Pattern)、元组模式 (Tuple Pattern)、位置模式 (Positional Pattern) 和 var 模式的扩展。
  • C# 9.0: 进一步增强了模式,引入了关系模式 (Relational Patterns)、逻辑模式 (Logical Patterns) 和括号模式 (Parenthesized Pattern),使得模式表达能力更加丰富。
  • C# 10.0: 优化了属性模式的语法,允许使用点符号访问嵌套成员。
  • C# 11.0: 引入了列表模式 (List Patterns),极大地简化了对列表或数组等集合类型进行匹配的操作。

本教程将覆盖这些版本中引入的核心模式和用法。

模式匹配的核心应用场景

C# 中的模式匹配主要体现在两个核心语言结构中:

  1. is 操作符表达式: 用于测试一个表达式的结果是否匹配某个模式,并可以选择性地将匹配成功后的值赋给新变量。
  2. switch 语句和 switch 表达式: 允许基于输入表达式匹配多个模式中的一个,并执行相应的代码块或计算相应的值。

接下来,我们将详细探讨各种模式及其在这两个场景下的应用。

一、基础模式与 is 操作符

is 操作符是最早支持模式匹配的结构之一。

1. 类型模式 (Type Pattern)

这是最基本也是最常用的模式。它检查表达式的结果是否是指定的类型,或者可以转换为该类型。

传统方式 (C# 6 及之前):

“`csharp
object obj = “Hello, Pattern Matching!”;

if (obj is string)
{
string s = (string)obj;
Console.WriteLine($”The string length is: {s.Length}”);
}
else if (obj is int)
{
int i = (int)obj;
Console.WriteLine($”The integer value is: {i}”);
}
// … 其他类型检查
“`

使用类型模式 (C# 7.0+):

“`csharp
object obj = “Hello, Pattern Matching!”;

// is Type variableName
if (obj is string s) // 类型模式 + 声明模式
{
// 如果 obj 是 string 类型,则匹配成功
// 并且 obj 的值会赋给新声明的 string 类型变量 s
// 变量 s 的作用域仅限于 if 块内部
Console.WriteLine($”The string length is: {s.Length}”);
}
else if (obj is int i) // 类型模式 + 声明模式
{
Console.WriteLine($”The integer value is: {i}”);
}
else if (obj is null) // 常量模式 (匹配 null)
{
Console.WriteLine(“Object is null”);
}

// 也可以只做类型检查,不声明变量
if (obj is string)
{
Console.WriteLine(“Object is definitely a string.”);
}
“`

注意 obj is string s 这种形式,它结合了类型模式 (string) 和声明模式 (Declaration Pattern)。声明模式允许在模式匹配成功时,将匹配到的值赋给一个新的、具有强类型的局部变量 (s),该变量的作用域通常限制在匹配发生的上下文中(如 if 语句块)。这极大地简化了类型检查和安全转换的常见模式。

2. 常量模式 (Constant Pattern)

常量模式用于测试表达式的结果是否等于一个指定的常量值。常用的常量包括:

  • null
  • 字符串字面量 ("hello")
  • 数值字面量 (10, 3.14)
  • 枚举成员 (FileMode.Open)
  • const 声明的常量

“`csharp
object input = null;

if (input is null)
{
Console.WriteLine(“Input is null.”);
}

input = 42;
if (input is 42)
{
Console.WriteLine(“Input is the answer to life, the universe, and everything.”);
}

string command = “START”;
if (command is “START”)
{
Console.WriteLine(“Processing START command…”);
}
“`

常量模式 null 对于空值检查非常方便和直观。

二、模式匹配与 switch 语句

C# 7.0 极大地增强了 switch 语句,使其能够处理类型模式和 when 子句。

1. case 中的类型模式

“`csharp
public static void ProcessShape(object shape)
{
switch (shape)
{
case Circle c: // 类型模式 + 声明模式
Console.WriteLine($”Circle with radius {c.Radius}”);
break;
case Rectangle r: // 类型模式 + 声明模式
Console.WriteLine($”Rectangle with width {r.Width} and height {r.Height}”);
break;
case Square s: // 类型模式 + 声明模式
Console.WriteLine($”Square with side {s.Side}”);
break;
case null: // 常量模式 (null)
Console.WriteLine(“Shape is null.”);
break;
default: // 默认情况
Console.WriteLine(“Unknown shape type.”);
break;
}
}

// 示例类
public class Circle { public double Radius { get; set; } }
public class Rectangle { public double Width { get; set; } public double Height { get; set; } }
public class Square { public double Side { get; set; } }

// 使用
ProcessShape(new Circle { Radius = 5 });
ProcessShape(new Rectangle { Width = 10, Height = 4 });
ProcessShape(null);
ProcessShape(“Not a shape”);
“`

在这个例子中,switch 语句根据 shape 对象的实际运行时类型来匹配不同的 case。如果匹配成功(例如 shape 是一个 Circle),那么该对象会被安全地转换为 Circle 类型并赋值给变量 c,然后执行相应的代码块。case null: 处理了输入为 null 的情况。

2. when 子句 (Case Guard)

when 子句允许为 case 添加额外的布尔条件。只有当类型匹配(或常量匹配)成功 并且 when 子句的条件为 true 时,该 case 才会被执行。

“`csharp
public static void ProcessShapeWithCondition(object shape)
{
switch (shape)
{
// 匹配非空、面积大于 100 的矩形
case Rectangle r when r.Width * r.Height > 100:
Console.WriteLine($”Large rectangle detected (Area: {r.Width * r.Height})”);
break;
// 匹配其他所有非空矩形
case Rectangle r:
Console.WriteLine($”Small or medium rectangle (Area: {r.Width * r.Height})”);
break;
// 匹配半径为 0 的圆 (可以认为是点)
case Circle c when c.Radius == 0:
Console.WriteLine(“Detected a point (Circle with radius 0).”);
break;
// 匹配其他所有非空圆
case Circle c:
Console.WriteLine($”Circle with radius {c.Radius}”);
break;
// 匹配一个特定的字符串常量
case “Special Shape”:
Console.WriteLine(“Handling the special shape string.”);
break;
case null:
Console.WriteLine(“Shape is null.”);
break;
default:
Console.WriteLine(“Unknown or unhandled shape type.”);
break;
}
}

// 使用
ProcessShapeWithCondition(new Rectangle { Width = 15, Height = 10 }); // Large rectangle
ProcessShapeWithCondition(new Rectangle { Width = 8, Height = 5 }); // Small or medium rectangle
ProcessShapeWithCondition(new Circle { Radius = 0 }); // Point
ProcessShapeWithCondition(new Circle { Radius = 7 }); // Circle
ProcessShapeWithCondition(“Special Shape”); // Special shape string
ProcessShapeWithCondition(null); // Null
ProcessShapeWithCondition(new Square { Side = 5 }); // Unknown
“`

重要提示: switch 语句中 case 的顺序很重要。运行时会按顺序检查 case,第一个匹配成功(包括 when 条件)的 case 会被执行,然后 switch 语句终止(除非使用 goto case 等特殊跳转)。因此,更具体的 case(例如带 when 子句的)通常应该放在更通用的 case(如只进行类型匹配的)之前。

三、switch 表达式 (C# 8.0+)

C# 8.0 引入了 switch 表达式,它提供了一种更简洁、基于表达式的 switch 逻辑形式。switch 表达式本身计算并返回一个值。

语法:

csharp
variable = inputExpression switch
{
pattern1 => resultExpression1,
pattern2 when condition => resultExpression2,
pattern3 => resultExpression3,
// ... 其他模式
_ => defaultResultExpression // _ 是弃元模式 (Discard Pattern),通常用于默认情况
};

特点:

  • 简洁: 使用 => 分隔模式和结果,无需 casebreak 关键字。
  • 表达式: 整个 switch 结构是一个表达式,可以赋值给变量、作为方法参数或方法返回值。
  • 详尽性 (Exhaustiveness): 编译器通常会检查 switch 表达式是否“详尽”,即是否覆盖了输入类型所有可能的值。如果不是(例如,缺少 _ 弃元模式作为默认情况),编译器会发出警告或错误(取决于上下文)。

示例:

“`csharp
public static string GetShapeDescription(object shape) => shape switch
{
Circle c when c.Radius > 10 => $”Large circle (R={c.Radius})”, // 类型 + when
Circle c => $”Standard circle (R={c.Radius})”, // 类型
Rectangle r when r.Width == r.Height => $”Square (Side={r.Width})”, // 类型 + when (模拟正方形)
Rectangle r => $”Rectangle (W={r.Width}, H={r.Height})”, // 类型
null => “Shape is null”, // 常量 (null)
“Point” => “It’s a point string”, // 常量 (string)
_ => “Unknown shape” // 弃元模式 (匹配任何其他情况)
};

// 使用
Console.WriteLine(GetShapeDescription(new Circle { Radius = 15 })); // Large circle (R=15)
Console.WriteLine(GetShapeDescription(new Circle { Radius = 5 })); // Standard circle (R=5)
Console.WriteLine(GetShapeDescription(new Rectangle { Width = 8, Height = 8 })); // Square (Side=8)
Console.WriteLine(GetShapeDescription(new Rectangle { Width = 10, Height = 6 })); // Rectangle (W=10, H=6)
Console.WriteLine(GetShapeDescription(null)); // Shape is null
Console.WriteLine(GetShapeDescription(“Point”)); // It’s a point string
Console.WriteLine(GetShapeDescription(123)); // Unknown shape
“`

switch 表达式极大地提升了根据条件返回值或执行简单逻辑的代码的清晰度。_ (下划线) 代表弃元模式 (Discard Pattern),它匹配任何值,但并不关心这个值是什么,通常用作 switch 表达式的最后一个分支,确保详尽性。

四、更多强大的模式类型 (C# 8.0+)

1. 属性模式 (Property Pattern)

属性模式允许你根据对象的属性值进行匹配。它使用花括号 {} 包裹属性及其期望的模式。

“`csharp
public record Address(string City, string Country);
public record Person(string Name, int Age, Address? HomeAddress);

public static string CheckPersonEligibility(Person person) => person switch
{
// 匹配 Age 属性大于等于 18 的 Person
{ Age: >= 18 } p => $”{p.Name} is an adult.”,

// 匹配 HomeAddress 不为 null 且 City 属性为 "London" 的 Person
{ HomeAddress: { City: "London" } } p => $"{p.Name} lives in London.",

// 匹配 HomeAddress 为 null 的 Person
{ HomeAddress: null } p => $"{p.Name} has no registered address.",

// 匹配 Name 为 "Alice" 的 Person (嵌套常量模式)
{ Name: "Alice" } => "Found Alice!",

// 匹配 Age 小于 18 的 Person
{ Age: < 18 } p => $"{p.Name} is a minor.",

// 默认情况
_ => "Person details do not match specific criteria."

};

// 使用
var alice = new Person(“Alice”, 30, new Address(“London”, “UK”));
var bob = new Person(“Bob”, 16, null);
var charlie = new Person(“Charlie”, 45, new Address(“Paris”, “France”));

Console.WriteLine(CheckPersonEligibility(alice)); // Found Alice! (Name match comes first)
// 如果调整顺序:
// { Age: >= 18 } p => $”{p.Name} is an adult.”,
// { HomeAddress: { City: “London” } } p => $”{p.Name} lives in London.”,
// …
// Console.WriteLine(CheckPersonEligibility(alice)); // Alice is an adult. (Age match would come first)

Console.WriteLine(CheckPersonEligibility(bob)); // Bob is a minor.
Console.WriteLine(CheckPersonEligibility(charlie)); // Charlie is an adult.
“`

属性模式非常强大,可以进行嵌套匹配(如 HomeAddress: { City: "London" }),并可以结合其他模式(如关系模式 Age: >= 18 或常量模式 Name: "Alice")。

2. var 模式

var 模式总是匹配成功,并将输入值赋给一个新的变量(类型由编译器推断)。它看起来像声明模式,但不执行类型检查。它常用于 switch 表达式中,当你想捕获一个值并在 when 子句中使用它,或者作为比弃元 _ 更具描述性的默认情况。

“`csharp
object data = 100;
string result = data switch
{
string s => $”String: {s}”,
int i when i > 50 => $”Large Int: {i}”,
var other => $”Caught something else: {other?.ToString() ?? “null”}” // var 模式捕获所有其他非 null 情况
};
Console.WriteLine(result); // Output: Large Int: 100

data = new List();
result = data switch
{
// … 其他 case
var capturedValue when capturedValue is System.Collections.IList list => $”Captured a list with {list.Count} items.”,
var capturedValue => $”Captured type: {capturedValue?.GetType().Name ?? “null”}”
};
Console.WriteLine(result); // Output: Captured a list with 0 items.
“`

3. 位置模式 (Positional Pattern)

位置模式用于解构元组 (Tuple) 或具有 Deconstruct 方法的对象。它根据值在结构中的“位置”进行匹配。

用于元组:

“`csharp
public static string DescribePoint(System.ValueTuple point) => point switch
{
(0, 0) => “Origin”, // 常量模式组合
(var x, 0) => $”On X-axis at {x}”, // var 模式 + 常量模式
(0, var y) => $”On Y-axis at {y}”, // 常量模式 + var 模式
(var x, var y) when x == y => $”On the line y=x at ({x},{y})”, // var + var + when
(int x, int y) => $”Generic point at ({x},{y})” // 类型模式 (可选, var 通常足够)
};

Console.WriteLine(DescribePoint((0, 0))); // Origin
Console.WriteLine(DescribePoint((5, 0))); // On X-axis at 5
Console.WriteLine(DescribePoint((0, -3))); // On Y-axis at -3
Console.WriteLine(DescribePoint((4, 4))); // On the line y=x at (4,4)
Console.WriteLine(DescribePoint((2, 7))); // Generic point at (2,7)
“`

用于具有 Deconstruct 方法的类型 (包括 C# 9+ 的 record):

“`csharp
// record 隐式提供了 Deconstruct 方法
public record Point(int X, int Y);

public static string DescribeRecordPoint(Point point) => point switch
{
(0, 0) => “Origin”,
(var x, 0) => $”On X-axis at {x}”,
(0, var y) => $”On Y-axis at {y}”,
( > 0, > 0) => “In the first quadrant”, // 关系模式组合
_ => “Somewhere else”
};

// 手动实现 Deconstruct 方法
public class Line
{
public Point Start { get; }
public Point End { get; }

public Line(Point start, Point end) { Start = start; End = end; }

// Deconstruct 方法允许按位置解构 Line 对象
public void Deconstruct(out Point start, out Point end)
{
    start = Start;
    end = End;
}

}

// 使用位置模式匹配 Line
public static void CheckLine(Line line)
{
switch (line)
{
// 匹配起点是原点的线段
case (Point(0, 0), var endPoint):
Console.WriteLine($”Line starts at origin and ends at {endPoint}”);
break;
// 匹配终点是原点的线段
case (var startPoint, Point(0, 0)):
Console.WriteLine($”Line starts at {startPoint} and ends at origin”);
break;
// 匹配起点和终点相同的线段 (一个点)
case (var p1, var p2) when p1.Equals(p2):
Console.WriteLine($”Line is just a point at {p1}”);
break;
default:
Console.WriteLine(“Regular line segment.”);
break;
}
}

// 使用
var p1 = new Point(0, 0);
var p2 = new Point(5, 5);
var p3 = new Point(1, 1);
CheckLine(new Line(p1, p2)); // Line starts at origin…
CheckLine(new Line(p2, p1)); // Line starts at Point { X = 5, Y = 5 } and ends at origin
CheckLine(new Line(p3, p3)); // Line is just a point at Point { X = 1, Y = 1 }
“`

位置模式提供了一种非常直观的方式来处理具有固定结构的数据。

五、高级模式 (C# 9.0+)

1. 关系模式 (Relational Patterns)

允许使用关系运算符 (<, >, <=, >=) 进行匹配。

“`csharp
public static string ClassifyTemperature(int temp) => temp switch
{
< 0 => “Freezing”,
0 => “Exactly zero”, // 常量模式
> 0 and <= 15 => “Cold”, // 逻辑 and 模式 + 关系模式
> 15 and <= 25 => “Mild”,
> 25 and < 35 => “Warm”,
>= 35 => “Hot”
// 注意: Switch 表达式需要详尽,这里覆盖了所有 int 值
};

Console.WriteLine(ClassifyTemperature(-5)); // Freezing
Console.WriteLine(ClassifyTemperature(10)); // Cold
Console.WriteLine(ClassifyTemperature(30)); // Warm
Console.WriteLine(ClassifyTemperature(40)); // Hot
“`

2. 逻辑模式 (Logical Patterns)

逻辑模式使用 and, or, not 关键字组合其他模式。

  • and: 要求两个模式都必须匹配。
  • or: 要求两个模式中至少有一个匹配。
  • not: 要求指定的模式不匹配。

“`csharp
public static string CheckValue(object value) => value switch
{
// 匹配大于 0 且小于 10 的整数
int i and > 0 and < 10 => “Single digit positive integer”,

// 匹配字符串 "Error" 或 "Warning"
"Error" or "Warning" => "Problem indicator string",

// 匹配不是 null 且不是字符串的值
not null and not string => "Not null and not a string",

// 匹配 null
null => "It's null",

// 匹配其他所有字符串
string s => $"Other string: {s}",

// 匹配其他所有情况 (包括非 int, 非 string, 非 null 的)
_ => "Something else entirely"

};

Console.WriteLine(CheckValue(5)); // Single digit positive integer
Console.WriteLine(CheckValue(“Warning”)); // Problem indicator string
Console.WriteLine(CheckValue(12.3)); // Not null and not a string
Console.WriteLine(CheckValue(null)); // It’s null
Console.WriteLine(CheckValue(“Info”)); // Other string: Info
“`

not 模式在需要排除特定情况时非常有用,例如 not null 是一个常见的组合。

3. 括号模式 (Parenthesized Pattern)

允许使用括号 () 来明确模式组合的优先级,就像在数学表达式中一样。

csharp
// 示例: 优先判断是否为 "High" 或 "Medium",然后判断是否非空
object priority = "High";
if (priority is ("High" or "Medium") and not null)
{
Console.WriteLine("Priority is High or Medium.");
}

虽然简单情况下括号不是必需的(因为 and 优先级高于 or),但在复杂组合中,它们可以提高清晰度并确保逻辑按预期执行。

六、列表模式 (List Patterns) (C# 11.0+)

列表模式是 C# 11 中引入的强大功能,专门用于匹配数组或列表等集合的元素。

语法:

使用方括号 [] 包裹元素模式。

  • []: 匹配空集合。
  • [pattern1]: 匹配只有一个元素且该元素匹配 pattern1 的集合。
  • [pattern1, pattern2]: 匹配恰好有两个元素,分别匹配 pattern1pattern2 的集合。
  • [pattern1, .., patternN]: ..切片模式 (Slice Pattern),匹配零个或多个元素。可以出现在模式的任何位置(最多一次)。
  • [_, pattern2, ..]: _ (弃元模式) 匹配单个元素,但不关心其值。

“`csharp
public static void AnalyzeSequence(int[] sequence)
{
switch (sequence)
{
// 匹配空数组
case []:
Console.WriteLine(“Empty sequence.”);
break;
// 匹配只有一个元素 0 的数组
case [0]:
Console.WriteLine(“Sequence contains only zero.”);
break;
// 匹配包含两个元素的数组,第一个是 1,第二个任意
case [1, _]:
Console.WriteLine(“Starts with 1, has two elements.”);
break;
// 匹配以 1 开头,后跟 2,然后任意数量元素 (包括 0 个) 的数组
case [1, 2, ..]:
Console.WriteLine(“Starts with 1, 2 sequence.”);
break;
// 匹配以 9 结尾的数组
case [.., 9]:
Console.WriteLine(“Ends with 9.”);
break;
// 匹配包含至少一个大于 100 的元素的数组 (使用切片和 when)
case [.., > 100, ..]:
Console.WriteLine(“Contains an element greater than 100.”);
break;
// 匹配包含三个元素的数组,并将它们赋值给变量
case [var first, var second, var third]:
Console.WriteLine($”Three elements: {first}, {second}, {third}”);
break;
// 默认情况
default:
Console.WriteLine(“Sequence doesn’t match specific patterns.”);
break;
}
}

// 使用
AnalyzeSequence(new int[] { }); // Empty sequence.
AnalyzeSequence(new int[] { 0 }); // Sequence contains only zero.
AnalyzeSequence(new int[] { 1, 5 }); // Starts with 1, has two elements.
AnalyzeSequence(new int[] { 1, 2, 3, 4 });// Starts with 1, 2 sequence.
AnalyzeSequence(new int[] { 5, 6, 9 }); // Ends with 9.
AnalyzeSequence(new int[] { 10, 20, 101, 30 }); // Contains an element greater than 100.
AnalyzeSequence(new int[] { 7, 8, 9 }); // Three elements: 7, 8, 9
AnalyzeSequence(new int[] { 1, 3, 5, 7 });// Sequence doesn’t match specific patterns.
“`

列表模式极大地简化了对集合结构和内容的判断,避免了之前需要手动检查长度和索引访问元素的繁琐代码。

七、模式匹配的最佳实践与注意事项

  1. 可读性优先: 模式匹配的主要目标之一是提高代码清晰度。如果一个复杂的模式变得难以理解,考虑将其拆分或使用更传统的方法(如辅助方法)。
  2. switchcase 的顺序:switch 语句和 switch 表达式中,模式是按顺序评估的。确保将更具体的模式放在更通用的模式之前,否则可能永远不会匹配到。例如,case Circle c when c.Radius > 10: 应放在 case Circle c: 之前。
  3. 空值处理: 显式处理 null 情况通常是个好主意。可以使用 case null: (switch 语句)、null => ... (switch 表达式) 或 is null (if 语句)。属性模式 { Property: pattern } 默认不匹配 null 对象,除非对象本身匹配且其属性也匹配。
  4. 详尽性: switch 表达式要求覆盖所有可能的输入(详尽性)。通常使用 _ 弃元模式作为最后一个分支来处理所有未明确匹配的情况。如果省略,且编译器无法证明所有情况都被覆盖,可能会产生警告或错误。switch 语句则不强制详尽性,未匹配的情况会直接跳过 switch 块(除非有 default 分支)。
  5. 性能: 模式匹配通常会被编译器优化,性能良好。但在极度性能敏感的代码路径中,仍需进行基准测试。简单的类型检查和常量比较通常非常快。复杂的模式(如涉及 when 子句或多层嵌套属性/列表模式)可能会有稍高的开销。
  6. 选择合适的工具:
    • 对于简单的类型检查和可选变量声明,is 操作符很方便。
    • 对于基于单一值执行不同代码块的多路分支,switch 语句(尤其是结合模式和 when)很强大。
    • 对于基于单一值计算并返回结果的多路分支,switch 表达式通常更简洁、更安全(得益于详尽性检查)。

总结

C# 模式匹配是现代 C# 开发工具箱中的一把瑞士军刀。它从 C# 7.0 的基础类型和常量模式开始,逐步发展到 C# 11.0 涵盖属性、位置、逻辑、关系乃至列表的复杂模式,极大地改变了我们编写条件逻辑和处理数据结构的方式。

通过熟练掌握 is 操作符和 switch 语句/表达式中的各种模式,您可以编写出更简洁、更具表现力、更不易出错的代码。它鼓励开发者以声明式的方式思考数据的“形状”,而不是陷入过程式的检查和转换细节中。

虽然模式匹配的语法初看起来可能有些复杂,但一旦理解了其核心概念和不同模式的用途,您会发现它能显著提高开发效率和代码质量。建议多加练习,在实际项目中尝试应用这些模式,逐步体会其带来的便利和优雅。模式匹配无疑是每个 C# 开发者都应该掌握的关键技能。


发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

滚动至顶部