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-声明和类型模式匹配的更多相关文章

  1. 代码的坏味道(6)——Switch声明(Switch Statements)

    坏味道--Switch声明(Switch Statements) 特征 你有一个复杂的 switch 语句或 if 序列语句. 问题原因 面向对象程序的一个最明显特征就是:少用 switch  和 c ...

  2. zendstudio 声明变量类型,让变量自动方法提示

    zendstudio 行内注释, 显式声明变量类型,让变量自动方法提示 $out = []; /* @var $row \xxyy\SizeEntity */ foreach ($rows[ 'lis ...

  3. Javascript声明变量类型

    声明变量类型 当您声明新变量时,可以使用关键词 "new" 来声明其类型: var carname=new String; var x= new Number; var y= ne ...

  4. swift 声明特性 类型特性

    原文地址:http://www.cocoachina.com/newbie/basic/2014/0612/8801.html 特性提供了关于声明和类型的很多其它信息.在Swift中有两类特性,用于修 ...

  5. switch的参数类型

    switch(expr1)中,expr1是一个整数表达式,整数表达式可以是int基本类型或Integer包装类型,由于,byte,short,char都可以隐含转换为int,所以,这些类型以及这些类型 ...

  6. 『忘了再学』Shell基础 — 19、使用declare命令声明变量类型

    目录 1.declare命令介绍 2.声明数组变量类型 3.声明变量为环境变量 4.声明只读属性 5.补充: 1.declare命令介绍 Shell中所有变量的默认类型是字符串类型,如果你需要进行特殊 ...

  7. java7 语法糖 之 switch 声明string

    Jdk7新switch 恒语句可以string种类. 例如: @Test public void test_1(){ String string = "hello"; switch ...

  8. c#如何声明数据结构类型为null?

    可以通过如下两种方式声明可为空的类型:System.Nullable<T> variable;T?variable:eg:int值是-2,147,483,648 到 2,147,483,6 ...

  9. SWIFT中用Switch case 类类型

    有时觉得SWIFT的语法真的强大而又变态,不说了,直接上代码瞅瞅: 首先先定义一个交通工具的父类 class Vehicle{ var wheels:Int! var speed:Double! in ...

  10. HTML头部声明文件类型

    在你每一个页面的顶端,你需要文件声明.是的,必须. 如果不指定文件类型,你的HTML不是合法的HTML,并且大部分浏览器会用“怪癖模式(quirks mode)”来处理页面,这意味着浏览器认为你自己也 ...

随机推荐

  1. 基于 Spring Cloud 的微服务脚手架

    基于 Spring Cloud 的微服务脚手架 作者: Grey 原文地址: 博客园:基于 Spring Cloud 的微服务脚手架 CSDN:基于 Spring Cloud 的微服务脚手架 本文主要 ...

  2. react 高效高质量搭建后台系统 系列 —— 请求数据

    其他章节请看: react 高效高质量搭建后台系统 系列 请求数据 后续要做登录模块(主页),需要先和后端约定JSON数据格式,将 axios 进行封装,实现本地的数据模拟 mockjs. Tip:s ...

  3. CLISP学习(二)

    它是一门函数式语言,你要用函数的思维来思考. 只不过与数学的表达不同的是,数学里的函数是在括号外  f(x) ,而lisp是在括号内,以列表的形式(f x), cos(x) --> (cos x ...

  4. s2-007

    漏洞名称 S2-007 CVE-2012-0838 远程代码执行 利用条件 Struts 2.0.0 - Struts 2.2.3 漏洞原理 age来自于用户输入,传递一个非整数给id导致错误,str ...

  5. SwiftUI(二)

    也许很多人看完一会有一个疑问,为什么UIHostingController我这里报错呢     看到这里大家心中的疑问也就解开了 接下来给大家说下@State的作用 通过@State swiftUI实 ...

  6. threeJs构建3D世界

    threejs官网 https://threejs.org/docs/index.html#manual/zh/introduction/Installation (官网非常的详细) 导入安装 npm ...

  7. Java 进阶P-6.6+P-7.1

    接口设计模式 接口 接口是纯抽象类 所有的成员函数都是抽象函数 所有的成员变量都是public static final 接规定了长什么样,但是不管里面有什么 实现接口 类用extends,接口用im ...

  8. immutable.js学习笔记(二)----- List

    一.List list与数组是兼容的,大多数的api与数组是类似的 注意 List.of(),不需要写中括号 二.List的API (一)size:取得 List 的长度 (二)set:设定指定下标的 ...

  9. Stats collector is not responding 统计信息收集器没有响应

    统计信息收集器没有响应/Stats collector is not responding 问题现象: kingbase数据库日志提示:统计信息收集器没有响应/Stats collector is n ...

  10. FAQ docker进程启动失败处理案例分享

    docker进程启动失败处理 背景 有同学反馈在启动docker的时候遇到了如下问题:docker启动报错 [root@wuxianfeng ~]# systemctl start docker Jo ...