模式匹配(Pattern Matching)是一种强大的特性,允许以简洁的方式检查和处理数据的类型、值或结构。相比传统的 if 语句,模式匹配可以让代码更简洁、可读性更高,尤其是在处理复杂条件或类型检查时。本文对 C# 模式匹配与 if 语句的对比和说明,重点介绍模式匹配的用法和优势。


模式匹配简介

C# 从 7.0 版本开始引入模式匹配,并随着版本迭代(如 8.0、9.0)不断增强。它主要用于:

  • • 检查对象的类型(类型模式)。
  • • 匹配常量或值(常量模式)。
  • • 检查对象的属性或结构(属性模式、递归模式等)。
  • • 简化条件逻辑,替代冗长的 if-else 结构。

主要场景:

  • is 运算符
  • switch 语句/表达式
  • when 子句结合模式匹配
  • • 解构(Deconstruction)和元组

常见形式

is 模式匹配

is 运算符用于检查类型并可直接声明变量

object value = 42;
if (value is int number)
{
    Console.WriteLine($"It's an integer: {number}");
}
  • 优势:无需显式类型转换(如 (int)value)。
  • 适用场景:简单类型检查、类型转换。

switch 语句中的模式匹配

C# 7.0 引入了增强的 switch 语句,支持类型模式和 when 子句:

object obj = 42;
switch (obj)
{
    caseint i when i > 0:
        Console.WriteLine("Positive integer");
        break;
    caseint i when i <= 0:
        Console.WriteLine("Non-positive integer");
        break;
    casestring s:
        Console.WriteLine($"String: {s}");
        break;
    casenull:
        Console.WriteLine("Null value");
        break;
    default:
        Console.WriteLine("Unknown type");
        break;
}
  • 优势:可以根据类型、值或条件进行分支处理,逻辑更清晰。
  • 适用场景:需要根据类型或条件执行不同逻辑。

switch 表达式(C# 8.0+)

switch 表达式是模式匹配的更简洁形式,返回值直接赋值:

object obj = "Hello";
string result = obj switch
{
    int i => $"Integer: {i}",
    string s when s.Length > 3 => $"Long string: {s}",
    string s => $"Short string: {s}",
    _ => "Unknown"
};
Console.WriteLine(result); // 输出:Long string: Hello
  • 优势:更简洁,适合返回值场景。
  • 适用场景:替代多分支 if-else 或简单的 switch 语句。

属性模式(Property Pattern, C# 8.0+)

属性模式允许检查对象的属性值:

public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

Person person = new Person { Name = "Alice", Age = 25 };
if (person is { Age: >= 18 })
{
    Console.WriteLine($"{person.Name} is an adult.");
}
  • 优势:直接匹配对象的属性,减少嵌套 if 语句。
  • 适用场景:需要检查对象属性的复杂条件。

元组和解构模式

模式匹配支持元组和解构,简化多值比较:

(int x, int y) point = (3, 4);
string location = point switch
{
    (0, 0) => "Origin",
    (var x, var y) when x > 0 && y > 0 => "First quadrant",
    _ => "Other"
};
Console.WriteLine(location); // 输出:First quadrant
  • 优势:直接解构并匹配元组中的值。
  • 适用场景:处理元组或多值数据。

模式匹配 vs. if 语句的优缺点

模式匹配的优点

    1. 简洁性:减少类型转换和冗余代码。
    1. 可读性:逻辑更清晰,尤其是处理复杂类型或条件时。
    1. 表达力:支持复杂模式(如属性模式、递归模式)。
    1. 类型安全:编译器确保类型检查和转换的安全性。

模式匹配的局限性

    1. 学习曲线:对于新手,模式匹配的语法可能稍复杂。
    1. 适用范围:在简单条件判断中,if 语句可能更直观。
    1. 性能:模式匹配通常与 if 性能相当,但在复杂场景下需注意编译器优化。

if 语句的优点

    1. 简单直观:适合简单逻辑或不涉及类型检查的场景。
    1. 灵活性:可以处理任意复杂条件,不局限于模式匹配支持的结构。
    1. 熟悉度:开发人员通常更熟悉 if 语句。

if 语句的局限性

    1. 冗长:类型检查和转换需要更多代码。
    1. 可读性:嵌套 if 可能导致代码难以维护。
    1. 错误风险:手动类型转换可能引发运行时异常。

模式匹配与 if 的综合对比的示例

使用 if 语句

public void ProcessShape(object shape)
{
    if (shape is Circle)
    {
        var circle = (Circle)shape;
        if (circle.Radius > 0)
        {
            Console.WriteLine($"Circle with radius {circle.Radius}");
        }
    }
    elseif (shape is Rectangle)
    {
        var rect = (Rectangle)shape;
        if (rect.Width > 0 && rect.Height > 0)
        {
            Console.WriteLine($"Rectangle with area {rect.Width * rect.Height}");
        }
    }
    else
    {
        Console.WriteLine("Unknown shape");
    }
}

使用模式匹配

public void ProcessShape(object shape)
{
    switch (shape)
    {
        case Circle { Radius: > 0 } c:
            Console.WriteLine($"Circle with radius {c.Radius}");
            break;
        case Rectangle { Width: > 0, Height: > 0 } r:
            Console.WriteLine($"Rectangle with area {r.Width * r.Height}");
            break;
        default:
            Console.WriteLine("Unknown shape");
            break;
    }
}
最后修改:2025 年 05 月 28 日
如果觉得我的文章对你有用,请随意赞赏