C# 9.0 新特性之模式匹配简化的实现
记得在MSBuild2020大会上,C#语言开发项目经理MadsTorgersen宣称C#9.0将会随着.NET5在今年11月份正式发布。目前.NET5已经到了Preview5阶段了,C#9.0也已经初具规模。忍不住激动的心情,暂停更新《C#.NET拾遗补漏》系列几天,先要和大家分享一下我了解到的C#9.0的新特性。由于新特性比较多,所以会分成几篇来讲。这是第一篇,专讲模式匹配这个特性的简化。
模式匹配(PatternMatching)是在C#7.0引入的,是对switch语句的增强,可以支持实现复杂的条件匹配。下面我先用一个示例来展示一下模式匹配的一般的用法。
假如现在我们要计算各种车辆在某高速的通行费,比如有下面四种车辆,分别定义为以下四个类,各个类中定义了和通行费计算相关的属性:
publicclassCar
{
publicintPassengers{get;set;}
}
publicclassDeliveryTruck
{
publicintGrossWeightClass{get;set;}
}
publicclassTaxi
{
publicintFares{get;set;}
}
publicclassBus
{
publicintCapacity{get;set;}
publicintRiders{get;set;}
}
下面用用模式匹配的方式来实现一个计算通行费的方法:
publicdecimalCalculateToll(objectvehicle)=>
vehicleswitch
{
Car{Passengers:0}=>2.00m+0.50m,
Car{Passengers:1}=>2.0m,
Car{Passengers:2}=>2.0m-0.50m,
Carc=>2.00m-1.0m,
Taxit=>t.Faresswitch
{
0=>3.50m+1.00m,
1=>3.50m,
2=>3.50m-0.50m,
_=>3.50m-1.00m
},
Busbwhen((double)b.Riders/(double)b.Capacity)<0.50=>5.00m+2.00m,
Busbwhen((double)b.Riders/(double)b.Capacity)>0.90=>5.00m-1.00m,
Busb=>5.00m,
DeliveryTrucktwhen(t.GrossWeightClass>5000)=>10.00m+5.00m,
DeliveryTrucktwhen(t.GrossWeightClass<3000)=>10.00m-2.00m,
DeliveryTruck_=>10.00m,
{}=>thrownewArgumentException(message:"Notaknownvehicletype",paramName:nameof(vehicle)),
null=>thrownewArgumentNullException(nameof(vehicle))
};
如果上面代码阅读起来感觉吃力,你可以先阅读文末参考链接中的第一个链接,关于模式匹配的详细介绍。
实现这个业务逻辑,若在C#7.0之前,需要用一堆的if/else来实现。有了模式匹配后,变得方便了很多,而且使用上很灵活,代码结构也更优美。
对我来说,模式匹配是个极好的特性!但这还不够,C#9.0对模式匹配的写法做了进一步的简化!
以上面代码为例,模式匹配可以分为三种:简单模式、关系模式和逻辑模式。下面分别说说C#9.0对三种模式的简化。
简单模式
以上面CalculateToll方法示例代码为例,简单模式是这种:
vehicleswitch
{
...
Carc=>2.00m-1.0m
}
我们其实可以发现,上面的变量c声明了却没用被使用,现在C#9.0中可以把它省略了:
vehicleswitch
{
...
Car=>2.00m-1.0m
}
关系模式
以上面CalculateToll方法示例代码为例,关系模式是通过比较(大小)关系来匹配的,对应的代码片段如下:
DeliveryTrucktwhen(t.GrossWeightClass>5000)=>10.00m+5.00m, DeliveryTrucktwhen(t.GrossWeightClass<3000)=>10.00m-2.00m, DeliveryTruck_=>10.00m,
现在C#9.0可以简写成:
DeliveryTrucktwhent.GrossWeightClassswitch
{
>5000=>10.00m+5.00m,
<3000=>10.00m-2.00m,
_=>10.00m,
}
逻辑模式
在C#9.0中,你可以通过逻辑操作符and、or和not对模式进行组合,下面是一些示例:
DeliveryTrucktwhent.GrossWeightClassswitch
{
<3000=>10.00m-2.00m,
>=3000and<=5000=>10.00m,
>5000=>10.00m+5.00m,
}
notnull=>thrownewArgumentException($"Notaknownvehicletype:{vehicle}",nameof(vehicle)),
null=>thrownewArgumentNullException(nameof(vehicle))
另外,not关键字还可以用来替代if条件判断中的逻辑非(!),比如:
//原来的写法
if(!(eisCustomer)){...}
//新的写法(易读性更好)
if(eisnotCustomer){...}
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