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

文章目录

  • 一、模式匹配
    • 1.1 Null检查
    • 1.2 类型测试
    • 1.3 比较离散值
    • 1.4 关系模式
    • 1.5 多个输入
    • 1.6 列表模式
    • 1.7 var
    • 1.8 对位模式
    • 1.9 扩展对位模式
    • 1.20 解构模式
    • 1.21 弃元模式
    • 1.22 属性模式
    • 1.23 分片模式


一、模式匹配

“模式匹配”是一种测试表达式是否具有特定特征的方法。 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" 

你可能感兴趣的:(.net及生态,.net,c#,c#模式匹配)