模式匹配性能更好,因为 C# 编译器会根据你的模式编译出最优的匹配路径。
switch 表达式
public static 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 => new RGBColor(0x4B, 0x00, 0x82), Rainbow.Violet => new RGBColor(0x94, 0x00, 0xD3), _ => throw new ArgumentException(message: "invalid enum value", paramName: nameof(colorBand)), };
属性模式
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) 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" };
位置模式
某些类型包含 Deconstruct
方法,该方法将其属性解构为离散变量。
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 };
模式匹配支持递归模式
string QueryMessage(Entry entry) { return entry switch { UserEntry u => dbContext1.User.FirstOrDefault(i => i.Id == u.UserId) switch { null => dbContext2.User.FirstOrDefault(i => i.Id == u.UserId)?.Content ?? "", var found => found.Content }, DataEntry d => dbContext1.Data.FirstOrDefault(i => i.Id == d.DataId) switch { null => dbContext2.Data.FirstOrDefault(i => i.Id == u.DataId)?.Content ?? "", var found => found.Content }, EventEntry { EventId: var eventId, CanRead: true } => dbContext1.Event.FirstOrDefault(i => i.Id == eventId) switch { null => dbContext2.Event.FirstOrDefault(i => i.Id == eventId)?.Content ?? "", var found => found.Content }, EventEntry { CanRead: false } => "", _ => throw new InvalidArgumentException("无效的参数") }; }