模式匹配在大数据中比较常用,比如scala语法中的模式匹配挺好用,它可以完美替换switch case语法(scala没有switch)。其实在C#语法中也有模式匹配,在C#7中就出现了模式匹配但不够完美,C#8之后增强了模式匹配的语法,让模式匹配变得更加简洁好玩。本文将简单讲讲模式匹配的使用。
这里我们以微软官方一个案例来举例说明模式匹配。案例是通过订单的数量和订单的总金额来确定折扣,参数是传入的记录类型,是订单的个数和订单总金额。传统的做法可以使用多个if判断或者用switch case语法,到了C#7可以用如下方法来做。.
//首先建一个订单类型
public record Order(int Items, decimal Cost);
//然后使用匹配模式判断
static decimal CalculateDiscount0(Order order)
{
switch (order)
{
case Order p when p.Items>10 && p.Cost>1000.00m:
return 0.10m;
case Order p when p.Items > 5 && p.Cost > 500.00m:
return 0.05m;
case Order p when p.Cost > 250.00m:
return 0.02m;
default:
return 0m;
}
}
//调用
static void Main(string[] args)
{
Order order1 =new(10,500.00m);
var rel= CalculateDiscount0(order1);
Console.WriteLine(rel);
}
//结果:0.02m
我们来看C#8之后版本的模式匹配写法:
//模式匹配方法 记录还是上面案例记录
public static decimal CalculateDiscount1(Order order) =>
order switch
{
Order p when p.Items > 10 && p.Cost > 1000.00m=> 0.10m,
Order p when p.Items > 5 && p.Cost > 500.00m=> 0.05m,
Order p when p.Cost > 250.00m => 0.02m,
null => throw new ArgumentNullException(nameof(order), "无法记录空订单"),
_ =>0m
};
//调用
static void Main(string[] args)
{
Order order1 =new(10,500.00m);
var rel= CalculateDiscount1(order1);
Console.WriteLine(rel);
}
//结果:0.02m
这是不是简洁多了,switch貌似成了个匿名方法委托,有点四不像了,好玩。还有更加简洁的方法,如下:
public static decimal CalculateDiscount2(Order order) =>
order switch
{
{ Items: > 10, Cost: > 1000.00m } => 0.10m,
{ Items: > 5, Cost: > 500.00m } => 0.05m,
{ Cost: > 250.00m } => 0.02m,
null => throw new ArgumentNullException(nameof(order), "无法记录空订单"),
var someObject => 0m,
};//调用省略
这是啥了,大括号套用大括号,感觉跟lambda有点相似了。里面的大括号可以换成小括号,那么就成了参数,必须有两个值。跟上面的例子比较更加简洁明了。如果把>换成=,那么还可以简洁。如下:
public static decimal CalculateDiscount3(Order order) =>
order switch
{
( 10, 1000.00m ) => 0.10m,
( 5, 500.00m) => 0.05m,
{Cost:> 250.00m } => 0.02m,//这个只能这么写。
null => throw new ArgumentNullException(nameof(order), "无法记录空订单"),
var someObject => 0m,
};//调用省略
代码量越来越少,是不是很好玩呢?
结语
本文讲述了C#模式匹配,这常用于大数据字符串的匹配,大家可以亲自试一试。微软的借鉴能力是越来越强了,它现在已经支持spark大数据了,看样子是要把.NET变为宇宙神器的节奏啊。希望本文对大家有所帮助,欢迎大家留言讨论。