switch-声明和类型模式匹配
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 };
switch-声明和类型模式匹配的更多相关文章
- 代码的坏味道(6)——Switch声明(Switch Statements)
坏味道--Switch声明(Switch Statements) 特征 你有一个复杂的 switch 语句或 if 序列语句. 问题原因 面向对象程序的一个最明显特征就是:少用 switch 和 c ...
- zendstudio 声明变量类型,让变量自动方法提示
zendstudio 行内注释, 显式声明变量类型,让变量自动方法提示 $out = []; /* @var $row \xxyy\SizeEntity */ foreach ($rows[ 'lis ...
- Javascript声明变量类型
声明变量类型 当您声明新变量时,可以使用关键词 "new" 来声明其类型: var carname=new String; var x= new Number; var y= ne ...
- swift 声明特性 类型特性
原文地址:http://www.cocoachina.com/newbie/basic/2014/0612/8801.html 特性提供了关于声明和类型的很多其它信息.在Swift中有两类特性,用于修 ...
- switch的参数类型
switch(expr1)中,expr1是一个整数表达式,整数表达式可以是int基本类型或Integer包装类型,由于,byte,short,char都可以隐含转换为int,所以,这些类型以及这些类型 ...
- 『忘了再学』Shell基础 — 19、使用declare命令声明变量类型
目录 1.declare命令介绍 2.声明数组变量类型 3.声明变量为环境变量 4.声明只读属性 5.补充: 1.declare命令介绍 Shell中所有变量的默认类型是字符串类型,如果你需要进行特殊 ...
- java7 语法糖 之 switch 声明string
Jdk7新switch 恒语句可以string种类. 例如: @Test public void test_1(){ String string = "hello"; switch ...
- c#如何声明数据结构类型为null?
可以通过如下两种方式声明可为空的类型:System.Nullable<T> variable;T?variable:eg:int值是-2,147,483,648 到 2,147,483,6 ...
- SWIFT中用Switch case 类类型
有时觉得SWIFT的语法真的强大而又变态,不说了,直接上代码瞅瞅: 首先先定义一个交通工具的父类 class Vehicle{ var wheels:Int! var speed:Double! in ...
- HTML头部声明文件类型
在你每一个页面的顶端,你需要文件声明.是的,必须. 如果不指定文件类型,你的HTML不是合法的HTML,并且大部分浏览器会用“怪癖模式(quirks mode)”来处理页面,这意味着浏览器认为你自己也 ...
随机推荐
- week_9(推荐系统)
Andrew Ng 机器学习笔记 ---By Orangestar Week_9(推荐系统) 1. Problem Formulation 这节就仅仅简单地介绍了一下 推荐系统的应用和实例.完全可以略 ...
- 【Vue】启动vue项目报错: errno: -4058, code: ‘ENOENT‘, syscall: ‘spawn cmd‘
运行vue项目(npm run dev)报错 报错如下 问题原因 缺少cmd运行程序的环境变量 解决方法在环境变量Path中加上C:\windows\system32
- Linux基础守护进程、高级IO、进程间通信
守护进程(Daemon) 前言 Linux常用于服务器,程序通常不运行在前台.运行于前台的进程和终端关联,一旦终端关闭,进程也随之退出.因为守护进程不和终端关联,因此它的标准输出和标准输入也无法工作, ...
- JavaScript:类(class)
在JS中,类是后来才出的概念,早期创造对象的方式是new Function()调用构造函数创建函数对象: 而现在,可以使用new className()构造方法来创建类对象了: 所以在很多方面,类的使 ...
- (4)go-micro微服务proto开发
目录 一 Protobuf介绍 二 安装Protobuf 三 Protobuf语法 1.1 基本规范 1.2 字段规则 1.3 service如何定义 1.4 Message如何定义 四 proto代 ...
- test20230109考试总结-2023寒搜索专题
前言 2023 年的第一篇考试总结-- 赛时得分情况: A B C D E F G \(\texttt{Total}\) \(\texttt{Rank}\) \(40\) \(80\) \(0\) \ ...
- 【ASP.NET Core】按用户角色授权
上次老周和大伙伴们分享了有关按用户Level授权的技巧,本文咱们聊聊以用户角色来授权的事. 按用户角色授权其实更好弄,毕竟这个功能是内部集成的,多数场景下我们不需要扩展,不用自己写处理代码.从功能语义 ...
- 03-逻辑综合工具 - Design Compiler
逻辑综合工具DC IC设计流程,市场-->制定spec-->RTL(同时进行sim,通过alint检查RTL有没有错误)-->systhesis(逻辑综合)-->PR(STA) ...
- vertica 7.0 使用kafka
config.propertiesclient.id设置为主机名或ip auto.offset.reset=smallest client.id=qas 设置环境变量 kafka_config=&qu ...
- centos7笔记本使用iptables服务,将笔记本模拟成为出口路由器 PPPOE拨号+NAT+端口映射
郑州洪水,闲置在家,捣鼓捣鼓 centos7笔记本使用iptables服务,将笔记本模拟成为出口路由器 PPPOE拨号+NAT+端口映射 环境: 1.笔记本单网口,无法做路由网关,手里有个闲置的USB ...