C# 8.0 添加和增强的功能【基础篇】( 二 )

3.2 属性模式借助属性模式,可以匹配所检查的对象的属性 。
如下电子商务网站的示例,该网站必须根据买家地址(Address 对象的 State 属性)计算销售税 。
// Address:地址对象;salePrice:售价public static decimal ComputeSalesTax(Address location, decimal salePrice) =>location switch{{ State: "WA" } => salePrice * 0.06M,{ State: "MN" } => salePrice * 0.075M,{ State: "MI" } => salePrice * 0.05M,// other cases removed for brevity..._ => 0M};此写法,使得整个语法更为简洁 。
3.3 元组模式日常开发中,存在算法依赖于多个输入 。使用元组模式,可根据 表示为元组 的多个值进行切换 。
// 游戏“rock, paper, scissors(石头剪刀布)”的切换表达式public static string RockPaperScissors(string first, string second)=> (first, second) switch{("rock", "paper") => "rock is covered by paper. Paper wins.",("rock", "scissors") => "rock breaks scissors. Rock wins.",("paper", "rock") => "paper covers rock. Paper wins.",("paper", "scissors") => "paper is cut by scissors. Scissors wins.",("scissors", "rock") => "scissors is broken by rock. Rock wins.",("scissors", "paper") => "scissors cuts paper. Scissors wins.",(_, _) => "tie" // 此处弃元 表示平局(石头剪刀布游戏)的三种组合或其他文本输入};3.4 位置模式某些类型包含 Deconstruct 方法,该方法将其属性解构为离散变量 。如果可以访问 Deconstruct 方法,就可以使用位置模式检查对象的属性并将这些属性用于模式 。
// 位于象限中的 点对象public class Point{public int X { get; }public int Y { get; }public Point(int x, int y) => (X, Y) = (x, y);public void Deconstruct(out int x, out int y) => (x, y) = (X, Y);}public enum Quadrant// 象限{Unknown, Origin, One, Two, Three, Four, OnBorder}// 下面的方法使用位置模式来提取 x 和 y 的值 。然后,它使用 when 子句来确定该点的 Quadrantstatic Quadrant GetQuadrant(Point point) => point switch{(0, 0) => Quadrant.Origin,var (x, y) when x > 0 && y > 0 => Quadrant.One,var (x, y) when x < 0 && y > 0 => Quadrant.Two,var (x, y) when x < 0 && y < 0 => Quadrant.Three,var (x, y) when x > 0 && y < 0 => Quadrant.Four,var (_, _) => Quadrant.OnBorder,// 当 x 或 y 为 0(但不是两者同时为 0)时,前一个开关中的弃元模式匹配_ => Quadrant.Unknown};如果没有在 switch 表达式中涵盖所有可能的情况,编译器将生成一个警告 。
四、using 声明using 声明是前面带 using 关键字的变量声明 。它指示编译器声明的变量应在封闭范围的末尾进行处理 。
static int WriteLinesToFile(IEnumerable<string> lines){using var file = new System.IO.StreamWriter("WriteLines2.txt");int skippedLines = 0;foreach (string line in lines){if (!line.Contains("Second"))file.WriteLine(line);elseskippedLines++;}return skippedLines;// 当代码运行到此位置时,file 被销毁// 相当于 using (var file = new System.IO.StreamWriter("WriteLines2.txt")){ ... }}如果 using 语句中的表达式不可用,编译器将生成一个错误 。
五、静态本地函数在C# 8.0中可以向本地函数添加 static 修饰符,以确保本地函数不会从封闭范围捕获(引用)任何变量 。若引用了就会生成报错:CS8421-“静态本地函数不能包含对 <variable> 的引用” 。
// 本地方法 LocalFunction 访问了方法 M() 这个封闭空间的变量 y// 因此,不能用 static 修饰符来声明int M(){int y;LocalFunction();return y;void LocalFunction() => y = 0;}// Add 方法可以是静态的,因为它不访问封闭范围内的任何变量int M(){int y = 5;int x = 7;return Add(x, y);static int Add(int left, int right) => left + right;}

经验总结扩展阅读