switch-声明和类型模式匹配
2024-10-07 19:16:43
1.声明和类型模式:类型为 T 的声明模式在表达式结果为非 NULL 且满足以下任一条件时与表达式匹配
var numbers = new int[] { 10, 20, 30 };
Console.WriteLine(GetSourceLabel(numbers)); // output: 1
var letters = new List<char> { 'a', 'b', 'c', 'd' };
Console.WriteLine(GetSourceLabel(letters)); // output: 2
static int GetSourceLabel<T>(IEnumerable<T> source) => source switch
{
Array array => 1,
ICollection<T> collection => 2,
_ => 3,
};
2.如果只想检查表达式类型,可使用弃元 _ 代替变量名,如以下示例所示:
public abstract class Vehicle {}
public class Car : Vehicle {}
public class Truck : Vehicle {}
public static class TollCalculator
{
public static decimal CalculateToll(this Vehicle vehicle) => vehicle switch
{
Car _ => 2.00m,
Truck _ => 7.50m,
null => throw new ArgumentNullException(nameof(vehicle)),
_ => throw new ArgumentException("Unknown type of a vehicle", nameof(vehicle)),
};
}
从 C# 9.0 开始,可对此使用类型模式,如以下示例所示:
public static decimal CalculateToll(this Vehicle vehicle) => vehicle switch
{
Car => 2.00m,
Truck => 7.50m,
null => throw new ArgumentNullException(nameof(vehicle)),
_ => throw new ArgumentException("Unknown type of a vehicle", nameof(vehicle)),
};
常量模式,从 C# 7.0 开始,可使用常量模式来测试表达式结果是否等于指定的常量,如以下示例所示:
public static decimal GetGroupTicketPrice(int visitorCount) => visitorCount switch
{
1 => 12.0m,
2 => 20.0m,
3 => 27.0m,
4 => 32.0m,
0 => 0.0m,
_ => throw new ArgumentException($"Not supported number of visitors: {visitorCount}",
nameof(visitorCount)),
};
在常量模式中,可使用任何常量表达式,例如: integer 或 floating-point 数值文本 char 或 string 文本 布尔值 true 或 false enum 值 声明常量字段或本地的名称 null
常量模式用于检查 null ,如以下示例所示:
if (input is null)
{
return;
}
Console.WriteLine(Classify(13)); // output: Too high
Console.WriteLine(Classify(double.NaN)); // output: Unknown
Console.WriteLine(Classify(2.4)); // output: Acceptable
static string Classify(double measurement) => measurement switch
{
< -4.0 => "Too low",
> 10.0 => "Too high",
double.NaN => "Unknown",
_ => "Acceptable",
};
Console.WriteLine(GetCalendarSeason(new DateTime(2021, 3, 14))); // output: spring
Console.WriteLine(GetCalendarSeason(new DateTime(2021, 7, 19))); // output: summer
Console.WriteLine(GetCalendarSeason(new DateTime(2021, 2, 17))); // output: winter
static string GetCalendarSeason(DateTime date) => date.Month switch
{
>= 3 and < 6 => "spring",
>= 6 and < 9 => "summer",
>= 9 and < 12 => "autumn",
12 or (>= 1 and < 3) => "winter",
_ => throw new ArgumentOutOfRangeException(nameof(date), $"Date with unexpected month: {date.Month}."),
};
逻辑模式-从 C# 9.0 开始,可使用 not 、 and 和 or 模式连结符来创建以下逻辑模式:
Console.WriteLine(Classify(13)); // output: High
Console.WriteLine(Classify(-100)); // output: Too low
Console.WriteLine(Classify(5.7)); // output: Acceptable
static string Classify(double measurement) => measurement switch
{
< -40.0 => "Too low",
>= -40.0 and < 0 => "Low",
>= 0 and < 10.0 => "Acceptable",
>= 10.0 and < 20.0 => "High",
>= 20.0 => "Too high",
double.NaN => "Unknown",
};
析取 or 模式在任一模式与表达式匹配时与表达式匹配,如以下示例所示:
Console.WriteLine(GetCalendarSeason(new DateTime(2021, 1, 19))); // output: winter
Console.WriteLine(GetCalendarSeason(new DateTime(2021, 10, 9))); // output: autumn
Console.WriteLine(GetCalendarSeason(new DateTime(2021, 5, 11))); // output: spring
static string GetCalendarSeason(DateTime date) => date.Month switch
{
3 or 4 or 5 => "spring",
6 or 7 or 8 => "summer",
9 or 10 or 11 => "autumn",
12 or 1 or 2 => "winter",
_ => throw new ArgumentOutOfRangeException(nameof(date), $"Date with unexpected month:
{date.Month}."),
};
and 模式连结符的优先级高于 or 。 要显式指定优先级,请使用括号,如以下示例所示:
static bool IsLetter(char c) => c is (>= 'a' and <= 'z') or (>= 'A' and <= 'Z');
属性模式 从 C# 8.0 开始,可使用属性模式来将表达式的属性或字段与嵌套模式进行匹配,如以下示例所示:
static bool IsConferenceDay(DateTime date) => date is { Year: 2020, Month: 5, Day: 19 or 20 or 21 };
Console.WriteLine(TakeFive("Hello, world!")); // output: Hello
Console.WriteLine(TakeFive("Hi!")); // output: Hi!
Console.WriteLine(TakeFive(new[] { '1', '2', '3', '4', '5', '6', '7' })); // output: 12345
Console.WriteLine(TakeFive(new[] { 'a', 'b', 'c' })); // output: abc
static string TakeFive(object input) => input switch
{
string { Length: >= 5 } s => s.Substring(0, 5),
string s => s,
ICollection<char> { Count: >= 5 } symbols => new string(symbols.Take(5).ToArray()),
ICollection<char> symbols => new string(symbols.ToArray()),
null => throw new ArgumentNullException(nameof(input)),
_ => throw new ArgumentException("Not supported input type."),
};
属性模式是一种递归模式。 也就是说,可以将任何模式用作嵌套模式。 使用属性模式将部分数据与嵌套模式进 行匹配,如以下示例所示:
public record Point(int X, int Y);
public record Segment(Point Start, Point End);
static bool IsAnyEndOnXAxis(Segment segment) =>
segment is { Start: { Y: 0 } } or { End: { Y: 0 } };
static bool IsAnyEndOnXAxis(Segment segment) => segment is { Start.Y: 0 } or { End.Y: 0 };
最新文章
- HADOOP安装指南-Ubuntu15.10和hadoop2.7.2
- HDU 2860 并查集
- URL编码与解码
- 利用jquery给指定的table动态添加一行、删除一行
- ios越狱开发第一次尝试记录
- MVC5 学习笔记2
- jquery 简单弹出层(转)
- 栈的顺序存储方式的C语言实现
- WCF技术剖析之三:如何进行基于非HTTP的IIS服务寄宿
- 为 .NET Core 设计一个 3D 图形渲染库
- Quartz学习——Quartz大致介绍(一)
- 芝麻HTTP:Ansible扩展
- Windows平台下kafka环境的搭建
- Asp.net core 学习笔记 (AutoMapper)
- Python之路PythonThread,第四篇,进程4
- asp.net core webapi 似乎未安装在 IIS 中承载 .NET Core 项目所需的 AspNetCoreModule。请尝试修复 Visual Studio 以纠正该问题。
- (转)Lua学习笔记1:Windows7下使用VS2015搭建Lua开发环境
- JDK观察者模式和事件机制比较<;转>;
- vue-cli 引入阿里巴巴字体图标:注意点
- SQL SERVER存储过程中使用事务与捕获异常
热门文章
- bitlocker加密如何找密钥解锁
- DID 2022-12-02
- Python + logging 控制台有日志输出,但日志文件中数据为空
- C++可执行文件绝对路径获取与屏蔽VS安全检查
- c#5.0(.net 4.5之后)的 Async+await+Task的异步机制的调试笔记
- [sklearn] 决策树、随机森林、隐马尔可夫模型
- [编程基础] C++多线程入门9-async教程和示例
- Educational Codeforces Round 141 (Rated for Div. 2) A-E
- 高并发解决方案orleans实践
- 算法学习笔记(9): 中国剩余定理(CRT)以及其扩展(EXCRT)