Switch expression cung cấp switch-like semantics trong expression context.
Switch là selection statement chọn single switch section để execute từ list candidates dựa trên pattern match với match expression.
Switch statement thường dùng như alternative cho if-else construct nếu single expression được test chống lại three hoặc more conditions.
Ví dụ
Cách mới viết Switch
var message = c switch {
Fruits.Red => "The Fruits is red",
Fruits.Green => "The Fruits is green",
Fruits.Blue => "The Fruits is blue"
};
Ví dụ 1
class Program {
public enum Fruits { Red, Green, Blue }
public static void Main() {
Fruits c = (Fruits)(new Random()).Next(0, 3);
// Cũ: Switch Statement
switch (c) {
case Fruits.Red:
Console.WriteLine("The Fruits is red");
break;
case Fruits.Green:
Console.WriteLine("The Fruits is green");
break;
case Fruits.Blue:
Console.WriteLine("The Fruits is blue");
break;
default:
Console.WriteLine("The Fruits is unknown.");
break;
}
// Mới: Switch Expression (C# 8.0)
var message = c switch {
Fruits.Red => "The Fruits is red",
Fruits.Green => "The Fruits is green",
Fruits.Blue => "The Fruits is blue"
};
System.Console.WriteLine(message);
Console.ReadLine();
}
}
Output
The Fruits is green The Fruits is green
Switch Expression Syntax Chi Tiết
// Basic syntax
var result = input switch {
pattern1 => expression1,
pattern2 => expression2,
_ => defaultExpression // Discard pattern (catch-all)
};
Pattern Matching trong Switch Expression
1. Type Pattern
public string Describe(object obj) => obj switch {
int i => $"Integer: {i}",
string s => $"String: {s}",
DateTime dt => $"Date: {dt:yyyy-MM-dd}",
null => "Null",
_ => "Unknown type"
};
2. Property Pattern
public string GetStatus(Order order) => order switch {
{ Status: OrderStatus.Pending } => "Pending",
{ Status: OrderStatus.Shipped, TrackingNumber: var tn } => $"Shipped: {tn}",
{ Status: OrderStatus.Delivered, DeliveryDate: var date } => $"Delivered on {date:d}",
{ Customer.IsVip: true } => "VIP Order",
_ => "Standard"
};
3. Tuple Pattern
public string RockPaperScissors(string player1, string player2) => (player1, player2) switch {
("Rock", "Scissors") => "Player 1 wins",
("Scissors", "Paper") => "Player 1 wins",
("Paper", "Rock") => "Player 1 wins",
(_, _) when player1 == player2 => "Tie",
_ => "Player 2 wins"
};
4. Relational Patterns (C# 9.0+)
public string GetGrade(int score) => score switch {
>= 90 => "A",
>= 80 => "B",
>= 70 => "C",
>= 60 => "D",
_ => "F"
};
5. Logical Patterns (and, or, not - C# 9.0+)
public bool IsValid(Product p) => p switch {
{ Price: > 0 and <= 1000, InStock: true } => true,
{ Price: < 0 or > 10000 } => false,
not null => true,
_ => false
};
Switch Expression vs Switch Statement
| Đặc điểm | Switch Statement | Switch Expression |
|---|---|---|
| Returns value | Không (void) | Có (expression-bodied) |
| Fall-through | Có (cần break) | Không (pattern matching) |
| Exhaustiveness | Không check | Compiler warning nếu thiếu case |
| Syntax | Statement-based | Expression-based (=>) |
| Variable assignment | Cần gán riêng | Direct assignment |
| Use in LINQ | Khó | Dễ dàng (expression) |
Expression-bodied Members với Switch Expression
public class Order {
public OrderStatus Status { get; set; }
public decimal Total { get; set; }
// Expression-bodied property
public string StatusDescription => Status switch {
OrderStatus.Pending => "Chờ xử lý",
OrderStatus.Processing => "Đang xử lý",
OrderStatus.Shipped => "Đã gửi hàng",
OrderStatus.Delivered => "Đã giao hàng",
OrderStatus.Cancelled => "Đã hủy",
_ => "Không xác định"
};
// Expression-bodied method
public decimal Discount => Total switch {
>= 1000000 => Total * 0.15m,
>= 500000 => Total * 0.10m,
>= 100000 => Total * 0.05m,
_ => 0
};
}