C# switch 表达式
上次修改时间:2024 年 1 月 19 日
在本文中,我们将展示如何在 C# 中使用 switch 表达式。
Switch 表达式 是对经典 switch 语句 的强大增强。它们由多个分支组成,每个分支都返回一个值。
分支可以评估以下内容:
- 值
- 类型
- 关系逻辑
- when 守卫
- 属性
- 元组
- 列表
C# switch 表达式值模式
使用值模式,switch 分支基于常量值,例如整数或字符串。
Console.Write("Enter a domain name: ");
string? domain = Console.ReadLine();
domain = domain?.Trim().ToLower();
string result = domain switch
{
"us" => "United States",
"de" => "Germany",
"sk" => "Slovakia",
"hu" => "Hungary",
_ => "Unknown"
};
Console.WriteLine(result);
在该示例中,我们使用 switch 表达式将国家/地区名称映射到其域名。
$ dotnet run Enter a domain name: sk Slovakia # dotnet run Enter a domain name: jp Unknown
C# switch 表达式类型模式
数据类型可以是 switch 表达式的模式。
int age = 23;
string name = "Peter";
List<string> colors = ["blue", "khaki", "orange"];
int[] nums = [1, 2, 3, 4, 5];
Console.WriteLine(check(age));
Console.WriteLine(check(name));
Console.WriteLine(check(colors));
Console.WriteLine(check(nums));
object check(object val) => val switch
{
int => "integer",
string => "string",
List<string> => "list of strings",
Array => "array",
_ => "unknown"
};
在该示例中,我们使用 switch 表达式找出变量的数据类型。
$ dotnet run integer string list of strings array
C# switch 表达式关系模式
可以使用关系模式构建强大的逻辑。
List<int> nums = [-3, 2, 0, 1, 9, -2, 7];
foreach (var num in nums)
{
var res = num switch
{
< 0 => "negative",
0 => "zero",
> 0 => "positive"
};
Console.WriteLine($"{num} is {res}");
}
我们有一个整数列表。在 foreach 循环中,我们遍历列表并使用 switch 表达式打印该值是负数、正数还是零。在 switch 表达式内部,我们使用简单的关系表达式。
$ dotnet run -3 is negative 2 is positive 0 is zero 1 is positive 9 is positive -2 is negative 7 is positive
C# switch 表达式 when 守卫
使用 when 守卫为我们的表达式分支增加了一些额外的灵活性。
List<User> users =
[
new ("John", "Doe", 34),
new ("Roger", "Roe", 44),
new ("Jane", "Doe", 44),
new ("Robert", "Molnar", 41),
new ("Lucia", "Petrovicova", 16),
];
foreach (var user in users)
{
Console.WriteLine(checkPerson(user));
}
string checkPerson(User u)
{
return u switch
{
{ LastName: "Doe" } => "Doe family",
{ Age: var age } when age < 18 => "minor person",
_ => $"{u}"
};
}
record User(string FirstName, string LastName, int Age);
在该示例中,我们使用 when 守卫来考虑 18 岁以下的用户。
$ dotnet run
Doe family
User { FirstName = Roger, LastName = Roe, Age = 44 }
Doe family
User { FirstName = Robert, LastName = Molnar, Age = 41 }
minor person
C# switch 表达式逻辑模式
and 和 or 运算符可以在 switch 表达式中使用。
List<User> users =
[
new ("Peter Novak", "driver", new DateTime(2000, 12, 1)),
new ("John Doe", "gardener", new DateTime(1996, 2, 10)),
new ("Roger Roe", "teacher", new DateTime(1976, 5, 9)),
new ("Lucia Smith", "student", new DateTime(2007, 8, 18)),
new ("Roman Green", "retired", new DateTime(1945, 7, 21)),
];
foreach (var user in users)
{
int age = GetAge(user);
string res = age switch
{
> 65 => "senior",
>= 18 and <= 64 => "adult",
< 18 => "minor",
_ => "unknown",
};
Console.WriteLine($"{user.Name} is {res}");
}
int GetAge(User user)
{
return (int)Math.Floor((DateTime.Now - user.Dob).TotalDays / 365.25D);
}
record User(string Name, string Occupation, DateTime Dob);
逻辑 and 运算符用于将 adult 字符串分配给年龄在 18 到 65 岁之间的用户。
$ dotnet run Peter Novak is adult John Doe is adult Roger Roe is adult Lucia Smith is minor Roman Green is senior
在以下示例中,我们有一个 or 表达式。
var q = @"
WWI started in:
1) 1912
2) 1914
3) 1918
";
Console.WriteLine(q);
var inp = Console.ReadLine();
var ans = int.Parse(inp.Trim());
var res = ans switch
{
1 or 3 => "Incorrect",
2 => "correct",
_ => "unknown option"
};
Console.WriteLine(res);
该示例检查用户的输入,并在 switch 表达式中使用 or 表达式。
C# switch 表达式属性模式
对象属性的值可以是 switch 表达式中的模式。
List<Product> products =
[
new ("Product A", 70m, 1, 10),
new ("Product B", 50m, 3, 15),
new ("Product C", 35m, 2, 20)
];
foreach (var product in products)
{
decimal sum = product switch
{
Product { Quantity: 2 } =>
product.Price * product.Quantity * (1 - product.Discount / 100m),
_ => product.Price * product.Quantity,
};
Console.WriteLine($"The final sum for {product.Name} is {sum}");
}
record Product(string Name, decimal Price, int Quantity, int Discount);
在该示例中,如果我们购买了该产品的两个商品,则将折扣应用于该产品的价格。
$ dotnet run The final sum for Product A is 70 The final sum for Product B is 150 The final sum for Product C is 56.0
已将 20% 的折扣应用于产品 C。
C# switch 表达式元组模式
switch 表达式可以使用元组模式。
while (true)
{
var menu = "Select: \n1 -> rock\n2 -> paper\n3 -> scissors\n4 -> finish";
Console.WriteLine(menu);
string[] options = {"rock", "paper", "scissors"};
int val;
try {
var line = Console.ReadLine();
if (string.IsNullOrEmpty(line))
{
Console.WriteLine("Invalid choice");
continue;
}
val = int.Parse(line);
} catch (FormatException)
{
Console.WriteLine("Invalid choice");
continue;
}
if (val == 4)
{
break;
}
if (val < 1 || val > 4)
{
Console.WriteLine("Invalid choice");
continue;
}
string human = options[val-1];
var rnd = new Random();
int n = rnd.Next(0, 3);
string computer = options[n];
Console.WriteLine($"I have {computer}, you have {human}");
var res = RockPaperScissors(human, computer);
Console.WriteLine(res);
}
Console.WriteLine("game finished");
string RockPaperScissors(string human, string computer) => (human, computer) switch
{
("rock", "paper") => "Rock is covered by paper. You loose",
("rock", "scissors") => "Rock breaks scissors. You win.",
("paper", "rock") => "Paper covers rock. You win.",
("paper", "scissors") => "Paper is cut by scissors. You loose.",
("scissors", "rock") => "Scissors are broken by rock. You loose.",
("scissors", "paper") => "Scissors cut paper. You win.",
(_, _) => "tie"
};
我们有一个石头剪刀布游戏,在其中我们利用元组表达式。
string RockPaperScissors(string human, string computer) => (human, computer) switch
{
("rock", "paper") => "Rock is covered by paper. You loose",
("rock", "scissors") => "Rock breaks scissors. You win.",
...
从人类和计算机的选择中,我们形成元组,这些元组用作 switch 表达式中的模式,以得出游戏结论。
$ dotnet run Select: 1 -> rock 2 -> paper 3 -> scissors 4 -> finish 1 I have rock, you have rock tie Select: 1 -> rock 2 -> paper 3 -> scissors 4 -> finish 2 I have paper, you have paper tie Select: 1 -> rock 2 -> paper 3 -> scissors 4 -> finish 3 I have paper, you have scissors Scissors cut paper. You win. Select: 1 -> rock 2 -> paper 3 -> scissors 4 -> finish 4 game finished
列表模式
自 C# 11 以来,switch 表达式分支可以评估列表模式。
List<Student> students = [
new ("John", ['a', 'b', 'a', 'c', 'd', 'd', 'e']),
new ("Lucia", ['b', 'b', 'c', 'c', 'a', 'e', 'e']),
new ("Paul", ['a', 'b', 'a', 'c', 'b', 'e', 'e']),
new ("Roger", ['a', 'c', 'c', 'c', 'a', 'b', 'e']),
new ("Michal", ['b', 'b', 'c', 'c', 'a', 'e', 'e']),
];
foreach (var student in students)
{
string res = student.Answers switch
{
['b', 'b', 'c', 'c', 'a', 'e', 'e'] => $"{student.Name} has passed",
_ => $"{student.Name} has failed"
};
Console.WriteLine(res);
}
record Student(string Name, List<char> Answers);
学生正在进行包含七个问题的测试。 这些问题的答案为“a”到“e”。 要通过测试,必须正确回答所有问题。
List<Student> students = [
new ("John", ['a', 'b', 'a', 'c', 'd', 'd', 'e']),
new ("Lucia", ['b', 'b', 'c', 'c', 'a', 'e', 'e']),
new ("Paul", ['a', 'b', 'a', 'c', 'b', 'e', 'e']),
new ("Roger", ['a', 'c', 'c', 'c', 'a', 'b', 'e']),
new ("Michal", ['b', 'b', 'c', 'c', 'a', 'e', 'e']),
];
这是学生及其测试答案的列表。
string res = student.Answers switch
{
['b', 'b', 'c', 'c', 'a', 'e', 'e'] => $"{student.Name} has passed",
_ => $"{student.Name} has failed"
};
我们根据正确答案检查结果。 该模式是一个字符列表,代表正确的答案。
$ dotnet run John has failed Lucia has passed Paul has failed Roger has failed Michal has passed
来源
switch 表达式 - 使用 switch 关键字的模式匹配表达式
在本文中,我们介绍了 C# switch 表达式。
作者
列出所有 C# 教程。