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