c#杂谈之四(模式匹配)


一、模式匹配

“模式匹配”是一种测试表达式是否具有特定特征的方法。 C# 模式匹配提供更简洁的语法,用于测试表达式并在表达式匹配时采取措施。 “is 表达式”目前支持通过模式匹配测试表达式并有条件地声明该表达式结果。 “switch 表达式”允许你根据表达式的首次匹配模式执行操作。 这两个表达式支持丰富的模式词汇。

1.1 Null检查

模式匹配最常见的方案之一是确保值不是 null。 使用以下示例进行 null 测试时,可以测试可为 null 的值类型并将其转换为其基础类型:

class Program
{
   
    static void Main()
    {
   

        //int? maybe = 12;
        int? maybe = null;
        if(maybe is int number) //
        {
   
            Console.WriteLine($"可为null的int maybe 具有值{
     number}");
        }
        else
        {
   
            Console.WriteLine("可为null的int 'maybe'不包含值");
        }
    }
}

上述代码是声明模式,用于测试变量类型并将其分配给新变量。 语言规则使此方法比其他方法更安全。 变量 number 仅在 if 子句的 true 部分可供访问和分配。 如果尝试在 else 子句或 if 程序块后等其他位置访问,编译器将出错。 其次,由于不使用 == 运算符,因此当类型重载 == 运算符时,此模式有效。 这使该方法成为检查空引用值的理想方法,可以添加 not 模式:

string? message = "This is not the null string";

if (message is not null)
{
   
    Console.WriteLine(message);
}

1.2 类型测试

模式匹配的另一种常见用途是测试变量是否与给定类型匹配。 例如,以下代码测试变量是否为非 null 并实现 System.Collections.Generic.IList 接口。 如果是,它将使用该列表中的 ICollection.Count 属性来查找中间索引。 不管变量的编译时类型如何,声明模式均与 null 值不匹配。 除了防范未实现 IList 的类型之外,以下代码还可防范 null。

public static T MidPoint<T>(IEnumerable<T> sequence)
{
   
    if (sequence is IList<T> list)
    {
   
        return list[list.Count / 2];
    }
    else if (sequence is null)
    {
   
        throw new ArgumentNullException(nameof(sequence), "Sequence can't be null.");
    }
    else
    {
   
        int halfLength = sequence.Count() / 2 - 1;
        if (halfLength < 0) halfLength = 0;
        return sequence.Skip(halfLength).First();
    }
}

1.3 比较离散值

public State PerformOperation(Operation command) =>
   command switch
   {
   
       Operation.SystemTest => RunDiagnostics(),
       Operation.Start => StartSystem(),
       Operation.Stop => StopSystem(),
       Operation.Reset => ResetToReady(),
       _ => throw new ArgumentException("Invalid enum value for command", nameof(command)),
   };

前一个示例演示了基于枚举值的方法调度。 最终 _ 案例为与所有数值匹配的弃元模式。 它处理值与定义的 enum 值之一不匹配的任何错误条件。 如果省略开关臂,编译器会警告你尚未处理所有可能输入值。 在运行时,如果检查的对象与任何开关臂均不匹配,则 switch 表达式会引发异常。 可以使用数值常量代替枚举值集。 你还可以将这种类似的方法用于表示命令的常量字符串值

public State PerformOperation(string command) =>
   command switch
   {
   
       "SystemTest" => RunDiagnostics(),
       "Start" => StartSystem(),
       "Stop" => StopSystem(),
       "Reset" 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

永恒的宁静

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值