时间:2021-05-20
记得在 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
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
C语言数据结构之模式匹配字符串定位问题主要实现了三种字符串的模式匹配,主要包括字符串子操作的集合,字符串指针回溯,和KMP算法头文件#ifndefINDEXHE
swiftwhere与匹配模式的实例详解前言:在众多Swift提供给Objective-C程序员使用的新特性中,有个特性把自己伪装成一个无聊的老头,但是却在如何
本文实例讲述了C#采用FileSystemWatcher实现监视磁盘文件变更的方法。分享给大家供大家参考。具体实现方法如下:简化需求:有一个简化了的需求是这样的
java模式匹配之蛮力匹配/***模式匹配之蛮力匹配*/packagejavay.util;/***PatternMatchBrute-Force*@autho
本文实例讲述了c#桥接模式(bridge结构模式)用法。分享给大家供大家参考。具体分析如下:一般来说,Bridge模式使用“对象间的组合关系”解耦了抽象和实现之