模式匹配增強功能
阿新 • • 發佈:2022-03-17
一.switch表示式
通常情況下, switch 語句在其每個 case 塊中生成一個值。 藉助 Switch 表示式,可以使用更簡潔的表示式語
法。 只有些許重複的 case 和 break 關鍵字和大括號。 以下面列出彩虹顏色的列舉為例:
public enum Rainbow { Red, Orange, Yellow, Green, Blue, Indigo, Violet }如果應用定義了通過 R 、 G 和 B 元件構造而成的 RGBColor 型別,可使用以下包含 switch 表示式的方法,將Rainbow 轉換為 RGB 值
public static這裡有幾個語法改進: 變數位於 switch 關鍵字之前。 不同的順序使得在視覺上可以很輕鬆地區分 switch 表示式和 switch 語句。 將 case 和 : 元素替換為 => 。 它更簡潔,更直觀。 將 default 事例替換為 _ 棄元。 正文是表示式,不是語句 將其與使用經典 switch 語句的等效程式碼進行對比:RGBColor FromRainbow(Rainbow colorBand) => colorBand
switch {
Rainbow.Red => new RGBColor(0xFF, 0x00, 0x00),
Rainbow.Orange => new RGBColor(0xFF, 0x7F, 0x00),
Rainbow.Yellow => new RGBColor(0xFF, 0xFF, 0x00),
Rainbow.Green => new RGBColor(0x00, 0xFF, 0x00),
Rainbow.Blue => new RGBColor(0x00, 0x00, 0xFF),
Rainbow.Indigo => newRGBColor(0x4B, 0x00, 0x82),
Rainbow.Violet => new RGBColor(0x94, 0x00, 0xD3),
_ => throw new ArgumentException(message: "invalid enum value", paramName: nameof(colorBand)),
};
publicstatic RGBColor FromRainbowClassic(Rainbow colorBand)
{
switch (colorBand)
{
case Rainbow.Red: return new RGBColor(0xFF, 0x00, 0x00);
case Rainbow.Orange: return new RGBColor(0xFF, 0x7F, 0x00);
case Rainbow.Yellow: return new RGBColor(0xFF, 0xFF, 0x00);
case Rainbow.Green: return new RGBColor(0x00, 0xFF, 0x00);
case Rainbow.Blue: return new RGBColor(0x00, 0x00, 0xFF);
case Rainbow.Indigo: return new RGBColor(0x4B, 0x00, 0x82);
case Rainbow.Violet: return new RGBColor(0x94, 0x00, 0xD3);
default: throw new ArgumentException(message: "invalid enum value", paramName: nameof(colorBand)); };
}
藉助屬性模式,可以匹配所檢查的物件的屬性。 請看一個電子商務網站的示例,該網站必須根據買家地址計算銷 售稅。 這種計算不是 Address 類的核心職責。 它會隨時間變化,可能比地址格式的更改更頻繁。 銷售稅的金額 取決於地址的 State 屬性。 下面的方法使用屬性模式從地址和價格計算銷售稅:
二.屬性模式
三.元組模式 一些演算法依賴於多個輸入。 使用元組模式,可根據表示為元組的多個值進行切換。 以下程式碼顯示了遊戲“rock, paper, scissors(石頭剪刀布)”的切換表示式::
public static decimal ComputeSalesTax(Address location, decimal salePrice)
=> location switch {
{ State: "WA" } => salePrice * 0.06M,
{ State: "MN" } => salePrice * 0.075M,
{ State: "MI" } => salePrice * 0.05M,
// other cases removed for brevity...
_ => 0M };
public static string RockPaperScissors(string first, string second) => (first, second)四.位置模式 某些型別包含 Deconstruct 方法,該方法將其屬性解構為離散變數。 如果可以訪問 Deconstruct 方法,就可以使 用位置模式檢查物件的屬性並將這些屬性用於模式。 考慮以下 Point 類,其中包含用於為 X 和 Y 建立離散變 量的 Deconstruct 方法:
switch { ("rock", "paper") => "rock is covered by paper. Paper wins.",
("rock", "scissors") => "rock breaks scissors. Rock wins.",
("paper", "rock") => "paper covers rock. Paper wins.",
("paper", "scissors") => "paper is cut by scissors. Scissors wins.",
("scissors", "rock") => "scissors is broken by rock. Rock wins.",
("scissors", "paper") => "scissors cuts paper. Scissors wins.",
(_, _) => "tie" };
public class Point此外,請考慮以下表示象限的各種位置的列舉:
{ public int X { get; }
public int Y { get; }
public Point(int x, int y) => (X, Y) = (x, y);
public void Deconstruct(out int x, out int y) => (x, y) = (X, Y);
}
public enum Quadrant { Unknown, Origin, One, Two, Three, Four, OnBorder }下面的方法使用位置模式來提取 x 和 y 的值。 然後,它使用 when 子句來確定該點的 Quadrant :
static Quadrant GetQuadrant(Point point) => point switch { (0, 0) => Quadrant.Origin, var (x, y) when x > 0 && y > 0 => Quadrant.One, var (x, y) when x < 0 && y > 0 => Quadrant.Two, var (x, y) when x < 0 && y < 0 => Quadrant.Three, var (x, y) when x > 0 && y < 0 => Quadrant.Four, var (_, _) => Quadrant.OnBorder, _ => Quadrant.Unknown };當 x 或 y 為 0(但不是兩者同時為 0)時,前一個開關中的棄元模式匹配。 Switch 表示式必須要麼生成值,要麼 引發異常。 如果這些情況都不匹配,則 switch 表示式將引發異常。 如果沒有在 switch 表示式中涵蓋所有可能的 情況,編譯器將生成一個警告。 可在此模式匹配高階教程中探索模式匹配方法。 有關位置模式的詳細資訊,請參閱模式的位置模式部分。