序列的 形狀 是圖案所需的可觀察性質集合。 這些屬性可能包括元素數量、每個元素或整個元素序列所寫的需求,以及特定索引處的標記值。 例如,一個形狀可能恰好需要兩個元素,索引 "Name" 為 0,或者它可能需要第一個標記、最後一個標記,以及它們之間的非空序列。
列表模式透過結合元素數量要求與有序位置的巢狀圖案來描述形狀。 它只測試模式中寫下的需求:元素子模式測試其對應元素,而 切片模式 則允許或測試一連串原本不匹配的元素。 你可以使用這些部分來比對確切的計數和標記值、擷取固定位置的值、允許中間部分不必匹配,或將巢狀模式套用至該中間部分。
當輸入的編譯時期型別具有 Length 或 Count 屬性,並支援索引式元素存取(也就是可依元素位置擷取元素)時,請選擇清單模式,如 input[index]。 陣列、List<T>字串和跨度是常見的範例。 編譯器會根據變數宣告的編譯時型別判斷資格,因為必須在程式執行前解析這些所需成員。
IEnumerable<T>介面本身提供列舉,而非這些成員,即使執行時物件是可索引的集合。
列表模式使用長度或計數及索引元素存取來取代列舉。 對於常見的內建型別,匹配只能檢查由模式命名的位置,而不必遍歷每個元素。 這些操作的成本取決於輸入類型。 迭代一個長集合可能需要時間,因此當決策需要檢視任意數量的元素而非特定位置時,建議使用迴圈或 LINQ。
完全匹配形狀
以下方法辨識雙欄標頭:
static bool IsHeader(string[] columns) =>
columns is ["Name", "Score"];
表達式 columns 就是模式輸入。
["Name", "Score"] 包含兩個常數模式。 精確列表模式省略切片模式,需要恰好兩個元素,並將每個巢狀模式套用到同一索引的元素上。 此模式描述具有確切數量和兩個標記值的形狀:索引 0 處為 "Name",索引 1 處為 "Score"。 巢狀元素模式為可選:空清單模式 [] 描述並匹配無元素的序列。
當形狀結合元素數量與有序位置的需求時,選擇列表模式。 如果只有元素數量才重要,則 a Length 或 Count 性質模式, items is { Count: 0 }例如 ,會更直接地表達這個意圖。
使用 discard 比對任何元素值
以下方法會從包含三個名字的完賽排序中讀取冠軍和第三名(季軍):
static string GetAnnouncements(List<string> finishingOrder) =>
finishingOrder switch
{
[var winner, _, var thirdPlace] =>
$"Winner: {winner}; third place: {thirdPlace}",
_ => "A complete three-runner result isn't available"
};
和 var winnervar thirdPlace 模式各自宣告一個變數。 當列表模式匹配時,C# 會將該位置的匹配元素值指派給對應變數,因此結果可以使用 winner 和 thirdPlace。 棄置模式 _ 接受第二個元素並丟棄其值。 此形狀需要恰好三個元素,賦予第一和第三位置特定意義,但不要求在任何位置的特定值。
當固定位置具有穩定意義時,請選擇此形式。 當你需要檢查任意數量的元素、轉換序列、搜尋序列或進行聚合時,可以使用迴圈或 LINQ。
允許其餘元素使用切片模式
在這個簡化的範例中,命令列可以以 --verbose 開頭,並包含其他參數,且假設以輸入檔名結尾。 以下方法辨識檔案名稱位於最後位置的形狀並擷取該值:
static string GetInputFile(string[] arguments) =>
arguments switch
{
["--verbose", .., var fileName] => $"Verbose processing: {fileName}",
[.., var fileName] => $"Processing: {fileName}",
[] => "No input file was provided"
};
切片模式..允許在第一個和最後一個元素之間剩餘零個或多個元素。 一個列表模式最多只能包含一個切片模式。 第一個切換臂描述的形狀至少包含兩個元素:索引 0 的標記 "--verbose" 、最後位置的檔案名稱,以及它們之間任意數量的不匹配參數。 獨立的切片並不測試中間的論點。 第二臂接受任意非空形狀並捕捉其最後一個元素,而空圖案則處理無元素的序列。
切片可以出現在列表模式的開始、中間或結尾。 當可變長度序列是形狀的一部分,但只有周圍位置需要元素測試時,才會使用它。 當每個元素都需要處理時,請使用普通迭代。
在切片上套用圖案
你可以對與 匹配 ..的零件套用另一種模式。 以下方法測試陣列是否以 開始 "BEGIN",以 "END"結尾,且兩者之間是否至少有一個元素:
static bool HasContent(string[] entries) =>
entries is ["BEGIN", .. { Length: > 0 }, "END"];
外層模式首先要求在索引 0 處有 "BEGIN" 標記,並在最後一個索引處有 "END"。 屬性模式 { Length: > 0 } 接著對切片匹配的序列增加了一個要求:它必須包含至少一個元素。 這些要求共同描述了完整的形狀。 這個圖案不會測試切片內元素的數值。
只有在中間部分本身需要進行比對或擷取時,才使用切片子模式。 如果只有邊界元素重要,普通元素 .. 就比較簡單。