博客 / 詳情

返回

C# 列表模式(List Patterns)深度解析:模式匹配再進化!

簡介

列表模式是一種模式匹配機制,允許檢查一個集合(例如數組、List<T>、或任何實現了 IEnumerable<T> 的類型)的元素數量、順序以及每個元素的內容。

C# 10 之前,模式匹配 (Pattern Matching) 已支持 switch 表達式、類型模式、屬性模式等,但對列表或序列的匹配還不夠直觀。
C# 11 引入 列表模式(List Patterns),讓開發者可以:

  • 按順序匹配數組、Span<T>IList<T> 等列表。
  • 檢查長度、特定元素,甚至解構其中的值。
  • 結合 switch、is、when 等模式匹配寫出簡潔、聲明式的代碼。
✅ 列表模式是模式匹配的擴展,不是新的集合類型。

語法

列表模式使用方括號 [] 來定義要匹配的模式:

基本形式:

[ element-pattern-1, element-pattern-2, ... ]
// 檢查列表是否恰好包含三個元素:1, 2, 3
if (list is [1, 2, 3])
{
    Console.WriteLine("列表包含精確序列 1, 2, 3");
}

元素模式可以是:

  • 常量(1、"abc")
  • 變量(var x)
  • 類型模式(int x)
  • 通配符(_)
  • 切片模式(..,C# 11 引入)
  • 嵌套模式({}、[] 等)

可以用於:

  • is 表達式
  • switch 表達式或語句
  • when 條件

匹配規則

  • 匹配順序嚴格一致。
  • 元素數量需滿足模式要求(可用切片模式放寬)。
  • 支持 IEnumerable、數組、Span<T>IList<T> 等實現 Length/Count 屬性 + 索引器 的類型。

基礎示例

精確匹配

int[] numbers = { 1, 2, 3 };

if (numbers is [1, 2, 3])
    Console.WriteLine("Exact match!");
只有當數組是 {1,2,3} 且長度為 3 時才匹配。

通配符 _

if (numbers is [1, _, 3])
    Console.WriteLine("Middle element can be anything");
忽略第二個元素,只要求首尾固定。

切片模式 ..

  • 匹配以 1 開頭的任意長度數組。
if (numbers is [1, ..])
    Console.WriteLine("Starts with 1");
  • 匹配以 3 結尾的數組。
if (numbers is [.., 3])
    Console.WriteLine("Ends with 3");
  • 開頭和結尾都可檢查,中間元素數量不限。
if (numbers is [1, .., 3])
    Console.WriteLine("Starts with 1 and ends with 3");

變量綁定

if (numbers is [1, .. var middle, 3])
    Console.WriteLine($"Middle elements count: {middle.Length}");
使用 var middle 捕獲中間切片。

類型模式

object[] items = { "hello", 42, 99 };

if (items is ["hello", int x, ..])
    Console.WriteLine($"Second element is int: {x}");
結合類型模式和切片。

空集合匹配

   if (arr is []) 
   {
       Console.WriteLine("Array is empty");
   }

嵌套列表模式

object[] data = [1, [2, 3], 4];

string result = data switch
{
    [1, [2, 3], 4] => "Nested match: [1, [2, 3], 4]",
    _ => "No match"
};

Console.WriteLine(result); // 輸出: Nested match: [1, [2, 3], 4]

結合 switch 表達式

int[] nums = { 1, 2, 3, 4 };

string result = nums switch
{
    [1, 2, 3, 4] => "Exact 1-2-3-4",
    [1, ..]      => "Starts with 1",
    [.., 4]      => "Ends with 4",
    []           => "Empty list",
    _            => "Other"
};
Console.WriteLine(result);

高級示例

斐波那契檢測

int[] fib = { 0, 1, 1, 2, 3, 5, 8 };

if (fib is [0, 1, .. var rest])
    Console.WriteLine($"Fibonacci sequence with {rest.Length + 2} elements");

解析命令行參數

string[] args = { "add", "user", "Alice" };

var command = args switch
{
    ["add", "user", var name] => $"Add user {name}",
    ["remove", "user", var name] => $"Remove user {name}",
    [] => "No command",
    _ => "Invalid"
};

Console.WriteLine(command);

帶 when 條件

if (numbers is [var first, .., var last] && first < last)
    Console.WriteLine($"First < Last ({first} < {last})");

適用場景

  • 數據驗證:檢查輸入的集合是否符合預期結構。
  • 數據提取:從集合中提取特定元素到變量,減少手動索引操作。
  • 簡化控制流:替代複雜的 if-else 或循環邏輯。
  • 遞歸處理:結合切片模式處理嵌套或不定長集合。
user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.