C# 中的模式匹配
模式匹配是測(cè)試表達(dá)式是否具有某一特性的方法。C# 提供了非常簡(jiǎn)潔優(yōu)雅的語(yǔ)法用于匹配模式并在匹配時(shí)執(zhí)行相應(yīng)的操作。
檢查匹配
模式匹配最高頻的場(chǎng)景是確保值不為 null。
public void IsMatch(int? number) { if (number is int n) { Console.WriteLine(#34;參數(shù) ‘number’ 具有值{n}”); } else { Console.WriteLine(“參數(shù)值為null”); } }
上述代碼使用 is 檢查 number 是否有值,若有,則賦給新變量 n。注意,新變量?jī)H在 if 語(yǔ)句塊中有效。
離散值匹配
檢查參數(shù)是否等于指定的值。支持的類型包括字符串和枚舉,從 C# 11 開(kāi)始,還支持 Span 和 ReadOnlySpan。
public string ConstantMatch(string? name) => name switch { “張三” => “我是張三”, “李四” => “我是李四”, _ => #34;我不知道自己是誰(shuí)” }; public string ConstantMatch(ReadOnlySpan name) => name switch { “張三” => “我是張三”, “李四” => “我是李四”, _ => #34;我不知道自己是誰(shuí)” };
上面的代碼,根據(jù) type 參數(shù)的值來(lái)返回不同的字符串。棄用符號(hào) _ 表示未在類表中定義的任意其它值,包括 null。
類型匹配
模式匹配的另一用途是檢查值是否與給定類型匹配。
public string TypeMatch(Animal? animal) => animal switch { Cat => “發(fā)現(xiàn)喵咪一只”, Dog => “發(fā)現(xiàn)汪汪一只”, null => “毛都沒(méi)發(fā)現(xiàn)”, _ => #34;發(fā)現(xiàn)不知道是啥的一個(gè)東西” };
上面的代碼,根據(jù) animal 參數(shù)的實(shí)際類型返回不同的字符串。棄元符號(hào) _ 表示未列出的任意其它值。
關(guān)系匹配
關(guān)系匹配可以將數(shù)值與常量進(jìn)行比較。
public string RelationalMatch(int age) => age switch { “嬰兒”, “幼兒”, “兒童”, “少年”, _ => “成年” };
上述代碼根據(jù) age 的值大小返回不同的值。棄元符號(hào) _ 表示未列出的任意其它值。
關(guān)系匹配模式還可以使用 and 和 or 來(lái)組合條件。
public static string GetWaterState(int temperature) => temperature switch { (> 0) and ( “液體”, “固體”, > 100 => “氣體”, 0 => “固體/液體臨界點(diǎn)”, 100 => “液體/氣體臨界點(diǎn)”, };
屬性匹配
還可以對(duì)指定對(duì)象的屬性進(jìn)行匹配,可以實(shí)現(xiàn)多個(gè)參數(shù)同時(shí)檢查。
public record Order(int Items, decimal Cost); public decimal CalculateDiscount(Order order) => order switch { (Items: > 10, Cost: > 1000.00m) => 0.10m, (Items: > 5, Cost: > 500.00m) => 0.05m, Order { Cost: > 250.00m } => 0.02m, null => throw new ArgumentNullException(nameof(order)), var someObject => 0m, };
上面的代碼中,前兩項(xiàng)檢查 Items 和 Cost 屬性的值。第三項(xiàng)只檢查了 Cost 屬性的值。第四項(xiàng)檢查是否為 null,第五項(xiàng)匹配任意其它值。