關係型與邏輯型態描述範圍、替代方案與排除。 以下方法將兩者結合以分類溫度:
static string ClassifyTemperature(int temperature) =>
temperature switch
{
< 0 => "Below freezing",
>= 18 and <= 24 => "Comfortable",
(>= 0 and < 10) or > 30 => "Far outside the comfortable range",
_ => "Cool or warm"
};
表達 temperature 式就是模式輸入。 C# 只會評估該運算式一次,而每個 switch 分支都會比對其結果值。 這些手臂展示了以下測試:
-
< 0測試其中一個邊界。 -
>= 18 and <= 24測試範圍。 -
(>= 0 and < 10) or > 30測試兩種替代射程。
本文展示了兩種模式與命令條件,讓你能學習每種形式,並比較它們如何表達相同的決策。 單一狀況在兩種形式下都可能相似。 模式能讓一系列相關分支更容易閱讀,因為將選擇與結果並列。 選擇最容易理解程式碼的形式。
比較數值與關係型態
關聯 型態 會透過使用 <、 >、 <=、 或 >=來比較其模式輸入與編譯時常數。
編譯時常數是編譯器在編譯程式時可以評估的值。 數值和字元常值,以及屬於相容之數值或字元型別的 const 變數,都是典型範例。 一般的變數、屬性、方法呼叫和 static readonly 欄位不是編譯時的常數。 在開頭的範例中,>= 18 和 <= 24 都會測試相同的已求值 temperature 值。
相同的關係符號可以出現在普通表達式或圖案中。 以下範例以溫度示範這兩種格式:
static void ShowExpressionAndPattern(int temperature, int threshold)
{
bool belowThreshold = temperature < threshold;
bool belowFreezing = temperature is < 0;
string description = temperature switch
{
< 0 => "Freezing",
0 => "Freezing point",
> 0 => "Above freezing"
};
Console.WriteLine(
$"Below threshold: {belowThreshold}; " +
$"below freezing: {belowFreezing}; {description}");
}
temperature < threshold 是一個 關係表達式。 它會評估兩個運算元並產生一個 bool。 任一運算元都可以是非恆定的表達式。
在 temperature is < 0中, temperature 是模式輸入表達式。 C# 會評估它,而關聯模式 < 0 則會測試所得值。 在 switch arm < 0 => "Freezing" 中,switch 前面的運算式提供輸入,因此該模式只包含 < 0。
該表達式可與 temperature 變數 threshold比較。 關聯模式運算元必須是編譯時常數,因此當比較值為變數時,請使用關聯式表達式。 當比較值為固定時,任一形式皆可運作。
當右運算元為常數時,主要以可讀性為考量來選擇。 關係表達式通常適合一個直接比較。 關係型態會與其他型態組成,當多個區間映射到切換結果時,自然契合。
將條件與邏輯模式結合
邏輯模式使用模式運算子 and、or 和 not 來結合或否定模式:
- 當兩個巢狀模式都相符時,
and模式就會相符。 - 當任一巢狀模式符合時,
or模式就會符合。 -
not模式會在其巢狀模式失敗時成功。
開頭的例子用 and 來描述一個範圍並 or 描述替代方案。
not模式可以排除某個值,例如 status is not Status.Complete。 以下方法展示兩種形式,讓你能學習它們的語法並比較它們如何表達同一測試:
static bool IsWeekendPattern(DayOfWeek day) =>
day is DayOfWeek.Saturday or DayOfWeek.Sunday;
static bool IsWeekendImperative(DayOfWeek day) =>
day == DayOfWeek.Saturday || day == DayOfWeek.Sunday;
該模式形式使用兩個常數模式,並由 or連接 。 命令式形式使用兩個相等性運算式,並以條件 OR 運算子 || 連接。 兩種形式都簡潔且清楚,適用於此單一條件。 選擇最適合周遭法規的形態。 模式通常會釐清 中 switch多個相關選擇,如開頭範例所示。
模式運算子形成模式而非布林表達式: and 對應模式合取、 or 模式替代方案及 not 模式否定。 布林表達式使用 &&、 ||、 !和 。 當多種圖案選擇結果相同時,選擇 or 。 當表達排除的模式比列出所有可接受的值更清楚時,請選擇 not。
括號內的群組模式
括號中的圖案使用括號來顯示或改變巢狀圖案的分組方式。 綁定決定運算子會將哪些模式中的運算元歸為一組,類似於未寫出括號時的隱式分組。 C# 規定了以下綁定順序:
notandor
以下測試接受優先順序1至3或特殊優先順序9:
static bool IsAcceptedPriority(int priority) =>
priority is (>= 1 and <= 3) or 9;
編譯器會先將 or 分組,再處理 and。 括號明確表示預期的分組,且兩種選項易於辨識:1 到 3 或 9 的範圍。 為了方便閱讀,當模式混合 and 和 or時 not ,或應用於複合模式時,請使用括號。 括號也可以改變預設分組,例如 not (>= 1 and <= 3)。
巢狀模式的執行時檢查順序未明確說明,且模式運算子遵循模式匹配規則,而非短路布林規則。 寫出巢狀模式,使其結果不受檢查順序影響。
when用護衛處理另一個病症
邏輯模式在巢狀模式描述輸入值本身時效果最佳。
when護線是標籤或開關臂上的case額外布林條件。 當決策也依賴與模式輸入不同的資訊時,使用護衛。
以下警告依溫度及獨立 isOutdoors 數值而定:
static string GetHeatWarning(int temperature, bool isOutdoors) =>
temperature switch
{
> 35 when isOutdoors => "High heat outdoors",
> 35 => "High heat",
_ => "No heat warning"
};
關係模式> 35描述了輸入。temperature 守衛 when isOutdoors 會檢查另一個數值。 當條件需要方法呼叫或布林運算式(但模式語法無法清楚表達)時,guard 也會被推薦。
當關聯模式和邏輯模式能讓輸入所允許的形式或值更容易看出時,請使用這些模式,尤其是在 switch 的多個分支中。 當它陳述直接條件更簡單時,使用普通的布林表達式。 當交換選擇依賴於獨立值或更適合用布林表達式表達的條件時,請使用 when 守衛。