C# 9.0 新特性之模式匹配简化的实现

记得在 MS Build 2020 大会上,C# 语言开发项目经理 Mads Torgersen 宣称 C# 9.0 将会随着 .NET 5 在今年 11 月份正式发布。目前 .NET 5 已经到了 Preview 5 阶段了,C# 9.0 也已经初具规模。忍不住激动的心情,暂停更新《C#.NET 拾遗补漏》系列几天,先要和大家分享一下我了解到的 C# 9.0 的新特性。由于新特性比较多,所以会分成几篇来讲。这是第一篇,专讲模式匹配这个特性的简化。

模式匹配(Pattern Matching)是在 C# 7.0 引入的,是对 switch 语句的增强,可以支持实现复杂的条件匹配。下面我先用一个示例来展示一下模式匹配的一般的用法。

假如现在我们要计算各种车辆在某高速的通行费,比如有下面四种车辆,分别定义为以下四个类,各个类中定义了和通行费计算相关的属性:

public class Car
{
  public int Passengers { get; set; }
}

public class DeliveryTruck
{
  public int GrossWeightClass { get; set; }
}

public class Taxi
{
  public int Fares { get; set; }
}

public class Bus
{
  public int Capacity { get; set; }
  public int Riders { get; set; }
}

下面用用模式匹配的方式来实现一个计算通行费的方法:

public decimal CalculateToll(object vehicle) =>
  vehicle switch
{
  Car { Passengers: 0}    => 2.00m + 0.50m,
  Car { Passengers: 1}    => 2.0m,
  Car { Passengers: 2}    => 2.0m - 0.50m,
  Car c            => 2.00m - 1.0m,

  Taxi t => t.Fares switch
  {
    0 => 3.50m + 1.00m,
    1 => 3.50m,
    2 => 3.50m - 0.50m,
    _ => 3.50m - 1.00m
  },

  Bus b when ((double)b.Riders / (double)b.Capacity) < 0.50 => 5.00m + 2.00m,
  Bus b when ((double)b.Riders / (double)b.Capacity) > 0.90 => 5.00m - 1.00m,
  Bus b => 5.00m,

  DeliveryTruck t when (t.GrossWeightClass > 5000) => 10.00m + 5.00m,
  DeliveryTruck t when (t.GrossWeightClass < 3000) => 10.00m - 2.00m,
  DeliveryTruck _ => 10.00m,

  { } => throw new ArgumentException(message: "Not a known vehicle type", paramName: nameof(vehicle)),
  null => throw new ArgumentNullException(nameof(vehicle))
};

代码来源于文末参考链接

如果上面代码阅读起来感觉吃力,你可以先阅读文末参考链接中的第一个链接,关于模式匹配的详细介绍。

实现这个业务逻辑,若在 C# 7.0 之前,需要用一堆的 if/else 来实现。有了模式匹配后,变得方便了很多,而且使用上很灵活,代码结构也更优美。

对我来说,模式匹配是个极好的特性!但这还不够,C# 9.0 对模式匹配的写法做了进一步的简化!

以上面代码为例,模式匹配可以分为三种:简单模式、关系模式和逻辑模式。下面分别说说 C# 9.0 对三种模式的简化。

简单模式

以上面 CalculateToll 方法示例代码为例,简单模式是这种:

vehicle switch
{
  ...
  Car c => 2.00m - 1.0m
}

我们其实可以发现,上面的变量 c 声明了却没用被使用,现在 C# 9.0 中可以把它省略了:

vehicle switch
{
  ...
  Car => 2.00m - 1.0m
}

关系模式

以上面 CalculateToll 方法示例代码为例,关系模式是通过比较(大小)关系来匹配的,对应的代码片段如下:

DeliveryTruck t when (t.GrossWeightClass > 5000) => 10.00m + 5.00m,
DeliveryTruck t when (t.GrossWeightClass < 3000) => 10.00m - 2.00m,
DeliveryTruck _ => 10.00m,

现在 C# 9.0 可以简写成:

DeliveryTruck t when t.GrossWeightClass switch
{
  > 5000 => 10.00m + 5.00m,
  < 3000 => 10.00m - 2.00m,
  _ => 10.00m,
}

逻辑模式

在 C# 9.0 中,你可以通过逻辑操作符 and、or 和 not 对模式进行组合,下面是一些示例:

DeliveryTruck t when t.GrossWeightClass switch
{
  < 3000 => 10.00m - 2.00m,
  >= 3000 and <= 5000 => 10.00m,
  > 5000 => 10.00m + 5.00m,
}

not null => throw new ArgumentException($"Not a known vehicle type: {vehicle}", nameof(vehicle)),
null => throw new ArgumentNullException(nameof(vehicle))

另外,not 关键字还可以用来替代 if 条件判断中的逻辑非(!),比如:

// 原来的写法
if (!(e is Customer)) { ... }

// 新的写法(易读性更好)
if (e is not Customer) { ... }

C# 9.0 还有很多其它好用的新特性,下一篇文章继续与你分享。文章写短一点不是因为我偷懒哈,而是为了促使大家一次性看完,方便大家在零碎时间阅读,避免因文章太长而成为“收藏不看”系列。

参考:

https://bit.ly/2MNc0DJ
https://bit.ly/2UzEIwu

到此这篇关于C# 9.0 新特性之模式匹配简化的实现的文章就介绍到这了,更多相关C# 9.0 模式匹配 内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

作者:王亮
出处:http://cnblogs.com/willick
联系:liam.wang@live.com

(0)

相关推荐

  • C#8 的模式匹配实现

    C# 7 里面的Pattern Mathing 更多内容请查看官方文档:https://docs.microsoft.com/zh-cn/dotnet/csharp/whats-new/csharp-8#more-patterns-in-more-places?WT.mc_id=DT-MVP-5003302 is 模式 switch 和 when C# 8 里面的Pattern Matching 使用Deconstructor 和 位置匹配模式 下面两个类Teacher和Student都由构造函

  • C# 9.0 新特性之模式匹配简化的实现

    记得在 MS Build 2020 大会上,C# 语言开发项目经理 Mads Torgersen 宣称 C# 9.0 将会随着 .NET 5 在今年 11 月份正式发布.目前 .NET 5 已经到了 Preview 5 阶段了,C# 9.0 也已经初具规模.忍不住激动的心情,暂停更新<C#.NET 拾遗补漏>系列几天,先要和大家分享一下我了解到的 C# 9.0 的新特性.由于新特性比较多,所以会分成几篇来讲.这是第一篇,专讲模式匹配这个特性的简化. 模式匹配(Pattern Matching)

  • 浅谈C#9.0新特性之参数非空检查简化

    参数非空检查是缩写类库很常见的操作,在一个方法中要求参数不能为空,否则抛出相应的异常.比如: public static string HashPassword(string password) { if(password is null) { throw new ArgumentNullException(nameof(password)); } ... } 当异常发生时,调用者很容易知道是什么问题.如果不加这个检查,可能就会由系统抛出未将对象引用为实例之类的错误,这不利于调用者诊断错误. 由

  • c# 9.0新特性nint和Pattern matching的使用方法

    一:背景 1. 讲故事 上一篇跟大家聊到了Target-typed new 和 Lambda discard parameters,看博客园和公号里的阅读量都达到了新高,甚是欣慰,不管大家对新特性是多头还是空头,起码还是对它抱有一种极为关注的态度,所以我的这个系列还得跟,那就继续开撸吧,今天继续带来两个新特性,更多新特性列表,请大家关注:新特性预览 二:新特性研究 1. Native ints 从字面上看貌似是什么原生类型ints,有点莫名其妙,还是看一看Issues上举得例子吧: Summar

  • 浅析C# 9.0 新特性之 Lambda 弃元参数

    大家好,这是 C# 9.0 新特性短系列的第 5 篇文章. 弃元(Discards) 是在 C# 7.0 的时候开始支持的,它是一种人为丢弃不使用的临时虚拟变量.语法上它是用来赋值的,但它却不被分配存储空间,即没有值,所以不能从中读取值.弃元用 _(下划线) 表示,下划线是一个关键字,只能赋值,不能读取,例如: 在 C# 7.0 中,弃元的使用场景主要有下面四种: 元组和对象的解构 使用 is 和 switch 的模式匹配 对具有 out 参数的方法的调用 作用域内独立使用场景 针对这几个场景,

  • C# 8.0新特性介绍

    C# 语言是在2000发布的,至今已正式发布了7个版本,每个版本都包含了许多令人兴奋的新特性和功能更新.同时,C# 每个版本的发布都与同时期的 Visual Studio 以及 .NET 运行时版本高度耦合,这也有助于开发者更好的学习掌握 C#,并将其与 Visual Studio 以及 .NET 的使用结合起来. 加快 C# 版本的发布速度 在被称为"新微软"的推动下,微软创新的步伐也加快了.为了做到加快步伐,微软开发部门将一些过去集成在一起的技术现在都分离了出来. Visual S

  • AngularJS 2.0新特性有哪些

    AngularJS已然成为Web应用开发世界里最受欢迎的开源JavaScript框架.自成立以来,见证其成功的是惊人的经济增长以及团体的支持与采用--包括个人开发者.企业.社区. Angular已经变成一个构建复杂单页面应用的客户端MVW框架(Model-View-Whatever).它在应用测试和应用编写方面都扮演重要角色,同时简化了开发过程. Angular目前的版本为1.3,该版本稳定,并被谷歌(框架维护者)用于支持众多应用(据估计,在谷歌有超过1600个应用运行于Angular1.2或1

  • C# 6.0 新特性汇总

    1. 静态using(static using) 静态using声明允许不使用类名直接调用静态方法. The static using declaration allows invoking static methods without the class name. In C# 5 using System; Console.WriteLine("Hello, World!"); In C# 6 using static System.Console; WriteLine("

  • Android Studio3.0新特性及安装图文教程

    Android Studio是Android的官方IDE.它是专为Android而打造,可以加快您的开发速度,帮助您为每款Android设备构建最优应用. 它提供专为Android开发者量身定制的工具,其中包括丰富的代码编辑.调试.测试和性能分析工具. 一.Android Studio3.0新特性 (1).核心IDE更改 我们将基础IDE从IntelliJ 2016.2升级到2017.1.2,在2016.3和 2017.1中增加了许多新功能, 包括参数提示,语义突出显示,搜索中的即时结果等等.

  • 详解Servlet3.0新特性(从注解配置到websocket编程)

    Servlet3.0的出现是servlet史上最大的变革,其中的许多新特性大大的简化了web应用的开发,为广大劳苦的程序员减轻了压力,提高了web开发的效率.主要新特性有以下几个: 引入注解配置 支持web模块化开发 程序异步处理 改进文件上传API 非阻塞式IO读取流 Websocket实时通信 一.注解配置 Servlet3.0新规范顺应了时代的潮流,使用注解配置,取代混乱的web.xml全局配置.在这之前我们在创建servlet,filter,listener时,都是在web.xml中配置

  • 简单了解Spring Framework5.0新特性

    SpringFramework5.0是自2013年12月版本4发布之后SpringFramework的第一个主发行版.SpringFramework项目的领导人JuergenHoeller于2016年7月28日宣布了第一个SpringFramework5.0里程碑版本(5.0M1). 现在,将近一年的时间过去以后,我们期盼已久的RC3版本将于2017年7月18日发行.这是路线图规划中SpringFramework5.0首个GA发行版的最后一次发行. 从高层来看,SpringFramework5.

随机推荐