C#9.0:Improved Pattern Matching

增强的模式匹配

C#9.0添加了几种新的模式。我们可以参阅模式匹配教程 ,来了解下面代码的上下文: 

 1 public static decimal CalculateToll(object vehicle) =>
 2     vehicle switch
 3     {
 4        ...
 5        
 6         DeliveryTruck t when t.GrossWeightClass > 5000 => 10.00m + 5.00m,
 7         DeliveryTruck t when t.GrossWeightClass < 3000 => 10.00m - 2.00m,
 8         DeliveryTruck _ => 10.00m,
 9 
10         _ => throw new ArgumentException("Not a known vehicle type", nameof(vehicle))
11     };

1、简单类型模式(Simple type patterns)

当前,进行类型匹配的时候,一个类型模式需要声明一个标识符——即使这标识符是一个弃元_,像上面代码中的DeliveryTruck_ 。但是在C#9.0中,你可以只写类型,如下所示: 

1 DeliveryTruck => 10.00m,

2、关系模式(Relational patterns)

C#9.0 提出了关系运算符<,<=等对应的模式。所以你现在可以将上面模式中的DeliveryTruck部分写成一个嵌套的switch表达式 

1 DeliveryTruck t when t.GrossWeightClass switch
2 {
3     > 5000 => 10.00m + 5.00m,
4     < 3000 => 10.00m - 2.00m,
5     _ => 10.00m,
6 },

 这里 > 5000 和 < 3000就是关系模式。

3、逻辑模式(Logical patterns)

最后,你可以用逻辑操作符and,or 和not将模式进行组合,这里的操作符用单词来表示,是为了避免与表达式操作符引起混淆。例如,上面嵌套的的switch示例,可以按照如下升序排序: 

1 DeliveryTruck t when t.GrossWeightClass switch
2 {
3     < 3000 => 10.00m - 2.00m,
4     >= 3000 and <= 5000 => 10.00m,
5     > 5000 => 10.00m + 5.00m,
6 },

此例中间的分支使用了and 来组合两个关系模式来形成了一个表达区间的模式。

not模式的常见的使用是将它用在null常量模式上,如not null。例如我们要根据是否为空来把一个未知分支的处理进行拆分: 

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

 此外,not 在 if 条件中包含 is 表达式时将会很方便,可以取代笨拙的双括号,例如:

if (!(e is Customer)) { ... }

你可以写成:

if (e is not Customer) { ... }

实际上,在is not表达式里,允许你给Customer指定名称,以便后续使用。

1 if (e is not Customer c) { throw ... } // 如果这个分支抛出异常或者返回...
2 var n = c.FirstName; // ... 这里,c肯定已经被赋值了,不会为空  
码字不易,欢迎关注,欢迎转载
作者:翁智华
本文采用「CC BY 4.0」知识共享协议进行许可,转载请注明作者及出处。
原文地址:https://www.cnblogs.com/wzh2010/p/14093998.html