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

此寫法,使得整個語法更為簡潔 。
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;}六、可處置的 ref 結構用 ref 修飾符聲明的 struct 可能無法實現任何接口,也包括接口 IDisposable 。
class Program{static void Main(string[] args){using (var book = new Book())Console.WriteLine("Hello World!");}}// 錯誤寫法// Error CS8343 'Book': ref structs cannot implement interfacesref struct Book : IDisposable{public void Dispose(){}}// 正確寫法class Program{static void Main(string[] args){// 根據 using 新特性,簡潔的寫法,默認在當前代碼塊結束前銷毀對象 bookusing var book = new Book();// ...}}ref struct Book{public void Dispose(){}}因此,若要能夠處理 ref struct,就必須有一個可訪問的 void Dispose() 方法 。
此功能同樣適用于 readonly ref struct 聲明 。
七、可為空引用類型若要指示一個變量可能為 null,必須在類型名稱后面附加 ?,以將該變量聲明為可為空引用類型 。否則都被視為不可為空引用類型 。
【C# 8.0 添加和增強的功能【基礎篇】】對于不可為空引用類型,編譯器使用流分析來確保在聲明時將本地變量初始化為非 Null 值 。字段必須在構造過程中初始化 。如果沒有通過調用任何可用的構造函數或通過初始化表達式來設置變量,編譯器將生成警告 。

推薦閱讀