一直用C#開發程式,.NET的功能越來越多,變化也挺大的,從最初的封閉,到現在的開源,功能不斷的增加,一直在進步。作為C#的強烈支持者,C#的變化,我不能不關註,這篇文章主要介紹,C#6.0和C#7.0增加的功能。C#的發展史和.NET以前的版本,請看C#和.NET版本,這邊文章中有介紹。 C# 6 ...
一直用C#開發程式,.NET的功能越來越多,變化也挺大的,從最初的封閉,到現在的開源,功能不斷的增加,一直在進步。作為C#的強烈支持者,C#的變化,我不能不關註,這篇文章主要介紹,C#6.0和C#7.0增加的功能。C#的發展史和.NET以前的版本,請看C#和.NET版本,這邊文章中有介紹。
C# 6.0版
1. 靜態導入
using static 增強功能可用於導入單個類的靜態方法。
例如:using static System.String;可以直接用String類中的靜態方法,而不用string.XXXX
2. 異常篩選器
“異常篩選器”是確定何時執行catch中的程式, 如果用於異常篩選器的表達式計算結果為 true,則 catch 子句將對異常執行正常處理,如果表達式計算結果為 false,則將跳過 catch 子句。
例如:e.Message.Contains("test")為true執行,否則不執行
try { throw new Exception("test"); } catch (Exception e) when (e.Message.Contains("test")) { Console.WriteLine("ce"); }
3. 只讀自動屬性、自動屬性初始化表達式、Expression bodied 成員、字元串內插
可以讓屬性初始化,僅僅初始化一次,這適用於方法和只讀屬性
例如:
public class Class6 { public string LastName { get; set; } public string FirstName { get; set; } public string FullName => $"{FirstName} {LastName}"; public override string ToString() => $"{FirstName},{LastName}"; } //調用 Class6 test = new Class6(); test.LastName = "jie"; test.FirstName = "hua"; Console.WriteLine($"FullName:{test.FullName}, ToString:{test.ToString()}"); test.LastName = "xiao jie"; Console.WriteLine($"FullName:{test.FullName}, ToString:{test.ToString()}"); //運行結果 //FullName:hua jie, ToString:hua,jie //FullName:hua xiao jie, ToString:hua,xiao jie
4. Null 傳播器
Null 條件運算符使 null 檢查更輕鬆、更流暢。 將成員訪問 . 替換為 ?.
例如:var first = person?.FirstName; string test = null;string t = test?.ToString();
如果 Person 對象是 null,則將變數 first 賦值為 null,否則,將 FirstName 屬性的值分配給該變數。【?.】的左側使用任何表達式(包括方法調用)
5. nameof 運算符
nameof 表達式的計算結果為符號的名稱,簡單來說就是為了顯示名稱。
例如: string test = "測試"; Console.WriteLine($"{test} , nameof:{nameof(test)}");
結果:測試 , nameof:test
6. 索引初始值設定項
索引初始值設定項就是對索引初始化,可以像Cat cat = new Cat { Age = 10, Name = "Fluffy" };初始化值一樣,只不過現在增加了索引的初始化
7. Catch 和 Finally 塊中的 Await
C# 5 對於可放置 await 表達式的位置有若幹限制。 使用 C# 6,現在可以在 catch 或 finally 表達式中使用 await。
例如:
try { throw new Exception("test"); } catch (Exception e) when (e.Message.Contains("test")) { await Task.Run(() => { Console.WriteLine($"await catch"); }); } finally { await Task.Run(() => { Console.WriteLine($"await finally"); }); }
C#7.0
1. Out 變數
現在可以在方法調用的參數列表中聲明 out 變數,而不是編寫單獨的聲明語句
例如:
if (int.TryParse("123", out int result)) Console.WriteLine(result)
2. 元組
需要包含多個數據元素的簡單結構的方法,也不知道怎麼解釋,總之就是好用。
例如:
(string Name, int Age) user = ("小紅", 18); Console.WriteLine($"Name:{user.Name}, Age:{user.Age}");
ValueTuple<string, int> valueTuple = new ValueTuple<string, int>("小紅", 18); //可以和Tuple對比學習 Tuple<string, int> test = new Tuple<string, int>("小紅", 18); //ValueTuple是值類型,Tuple是引用類型
3. 模式匹配
模式匹配 是一種可讓你對除對象類型以外的屬性實現方法分派的功能,模式匹配支持 is 表達式和 switch 表達式。每個表達式都允許檢查對象及其屬性以確定該對象是否滿足所尋求的模式,使用 when 關鍵字來指定模式的其他規則。is 表達式的增強功能, 可以針對值類型和引用類型進行測試。簡單來說就是幫你測試類型。
例如:
string test = "123"; if (test is int count) Console.WriteLine(count);
上面的例子會提示int類型的模式無法處理string類型的表達式。
4. 本地函數
許多類的設計都包括僅從一個位置調用的方法。 這些額外的私有方法使每個方法保持小且集中。 本地函數使你能夠在另一個方法的上下文內聲明方法 。 本地函數使得類的閱讀者更容易看到本地方法僅從聲明它的上下文中調用。簡單來說就是方法中寫方法。
例如:
public static int Test() { int count = Add(12, 10); return count; int Add(int a, int b) { return a + b; } }
5. Ref 局部變數和返回結果
此功能允許使用並返回對變數的引用的演算法,這些變數在其他位置定義。
例如:
class NumberStore { int[] numbers = { 1, 3, 7, 15, 31, 63, 127, 255, 511, 1023 }; public ref int FindNumber(int target) { for (int ctr = 0; ctr < numbers.Length; ctr++) { if (numbers[ctr] >= target) return ref numbers[ctr]; } return ref numbers[0]; } public override string ToString() => string.Join(" ", numbers); } var store = new NumberStore(); Console.WriteLine($"Original sequence: {store.ToString()}"); int number = 16; ref var value = ref store.FindNumber(number); value *= 2; Console.WriteLine($"New sequence: {store.ToString()}"); // The example displays the following output: // Original sequence: 1 3 7 15 31 63 127 255 511 1023 // New sequence: 1 3 7 15 62 63 127 255 511 1023
31變成62了,對象中的數組值改變了,這個功能覺得要慎用。
6. 棄元
通常,在進行元組解構或使用 out 參數調用方法時,必須定義一個其值無關緊要且你不打算使用的變數。 為處理此情況,C# 增添了對棄元的支持 。 棄元是一個名為 _(下劃線字元)的只寫變數,可向單個變數賦予要放棄的所有值。 棄元類似於未賦值的變數;不可在代碼中使用棄元(賦值語句除外)。簡單來說就是放棄不需要的值。
例如:
private static (string, double, int) Test(string name) { return (name, 1.234, 20); } //使用 var (name, _, age) = Test("測試"); Console.WriteLine($"測試棄元: Name:{name}, Age:{age}"); //運行結果:測試棄元: Name:測試, Age:20
7. 二進位文本和數字分隔符
誤讀的數值常量可能使第一次閱讀代碼時更難理解。 位掩碼或其他符號值容易產生誤解。 C# 7.0 包括兩項新功能,可用於以最可讀的方式寫入數字來用於預期用途:二進位文本和數字分隔符 。簡單來說就是可以把數字分割等
例如:
int test = 1_123_21; Console.WriteLine(test); //結果 112321
8. 引發表達式
throw 始終是一個語句。 因為 throw 是一個語句而非表達式,所以在某些 C# 構造中無法使用它。
例如:string test = false ? "" : throw new Exception("必須是字元串,否則報錯。");
9. 增加非同步返回類型ValueTask
非同步方法返回類型不限於 Task、Task<T> 和 void,可以是ValueTask<int>,可避免在性能上分配 Task。
可以查看 【C#中await/async閑說】,這篇文章對非同步性能進行了說明,對ValueTask的使用進行了說明
其他的版本的基礎功能
5. C#中泛型的解釋(object,list,var,dynamic的區別)
6. C#中委托
7. C#和.NET版本對比