1) async / await
使用 async / await 模式,可以在執行程式碼塊操作的時候不會阻塞 UI 或者當前的執行緒。即使該操作被某些執行動作延遲了(比如一個 web 請求),async / await 模式也會繼續執行後續的程式碼。
更多關於 async / await 模式的內容,請見:https://msdn.microsoft.com/zh-cn/library/hh191443.aspx
2) 物件 / 陣列 / 集合的初始值設定項(initializers)
通過使用物件、陣列、集合的初始值設定項,可以很容易地建立類、陣列和集合的例項:
1 2 3 4 5 6 7 8 |
// 示例類 public class Employee { public string Name {get; set;} public DateTime StartDate {get; set;} } // 使用初始值設定項建立員工例項 Employee emp = new Employee {Name="John Smith", StartDate=DateTime.Now()}; |
上述示例中的程式碼在單元測試中可能非常有幫助,不過在有些情況下也應該避免使用它,比如應該通過建構函式來進行類的例項化的時候。
更多關於初始值設定項的內容,請見:https://msdn.microsoft.com/zh-cn/library/bb384062.aspx
3) Lambda 表示式、謂詞委託(predicates)、委託(delegates)和閉包(closures)
這些特性在很多情況下都是非常必要的(比如使用 Linq 的時候),請務必學習在何時以及如何使用它們。
更多關於 Lambda 表示式、謂詞委託、委託和閉包的內容,請見:http://www.codeaddiction.net/articles/13/lambda-expressions-delegates-predicates-and-closures-in-c
4) ?? – null 合併運算子(Null coalescing operator)
當表示式左側不為 null 的時候,?? 運算子返回其左側的值,否則返回其右側的值:
1 2 3 4 5 6 |
// 可能是 null var someValue = service.GetValue(); var defaultValue = 23 // 如果 someValue 是 null 的話,result 為 23 var result = someValue ?? defaultValue; |
?? 運算子可以用於鏈式操作:
1 |
string anybody = parm1 ?? localDefault ?? globalDefault; |
它也可以將可空型別轉換為非可空型別:
1 |
var totalPurchased = PurchaseQuantities.Sum(kvp => kvp.Value ?? 0); |
更多關於 ?? 運算子的內容,請見:https://msdn.microsoft.com/zh-cn/library/ms173224.aspx
5) $”{x}” – 內插字串(String Interpolation)- C# 6
C# 6 的一個新特性,可以通過更加高效和優雅的方式來進行字串拼接:
1 2 3 4 5 |
// 傳統方式 var someString = String.Format("Some data: {0}, some more data: {1}", someVariable, someOtherVariable); // 新的方式 var someString = $"Some data: {someVariable}, some more data: {someOtherVariable}"; |
也可以在大括號中寫 C# 表示式,這讓它變得非常強大。
6) ?. – null 條件運算子(Null-conditional operator) – C# 6
null 條件運算子使用起來如下所示:
1 2 |
// 如果 customer 或 customer.profile 或 customer.profile.age 為 null 的話,結果都是 null var currentAge = customer?.profile?.age; |
不再會發生 NullReferenceExceptions 了!
更多關於 ?. 運算子的內容,請見:https://msdn.microsoft.com/zh-cn/library/dn986595.aspx
7) nameof 表示式 – C# 6
新的 nameof 表示式可能看上去沒那麼重要,不過它確實也有其用武之地。在使用自動重構工具(比如 Resharper)時,你可能會需要通過引數的名字來表示它:
1 2 3 4 5 6 7 8 |
public void PrintUserName(User currentUser) { // 在重新命名 currentUser 的時候,重構工具可能會遺漏在文字中的這個變數名 if(currentUser == null) _logger.Error("Argument currentUser is not provided"); //... } |
現在你可以這樣來寫:
1 2 3 4 5 6 7 8 |
public void PrintUserName(User currentUser) { // 重構工具不會漏掉這個 if(currentUser == null) _logger.Error($"Argument {nameof(currentUser)} is not provided"); //... } |
更多關於 nameof 表示式的內容,請見:https://msdn.microsoft.com/zh-cn/library/dn986596.aspx
8) 屬性初始值設定項 – C# 6
你可以通過屬性初始值設定項,在宣告一個屬性的時候指定一個初始值:
1 2 3 4 5 |
public class User { public Guid Id { get; } = Guid.NewGuid(); // ... } |
使用屬性初始值設定項的一個好處,就是你不必宣告一個 setter 方法,從而使得該屬性成為不可變的(immutable)。屬性初始值設定項可以和 C# 6 的主建構函式(Primary Constructor)語法配合使用。(譯者注:Primary Constructor 語法可以讓你在定義一個類的同時,在類名之後立即指定一個帶引數的建構函式)
9) as / is 運算子
is 運算子用來判斷一個例項是否是特定型別的,比如你想看一下型別轉換是否是可行的:
1 2 3 4 |
if (Person is Adult) { //do stuff } |
as 運算子會試圖將某個物件轉換為某個特定類的例項。如果無法轉換的話會返回 null:
1 2 3 4 5 |
SomeType y = x as SomeType; if (y != null) { //do stuff } |
10) yield 關鍵字
你可以通過 yield 關鍵字來返回 IEnumerable 介面的資料項。下面的示例會返回 2 的次方(比如直到 8 次方:2、4、8、16、32、64、128、256):
1 2 3 4 5 6 7 8 9 |
public static IEnumerable<int> Power(int number, int exponent) { int result = 1; for (int i = 0; i < exponent; i++) { result = result * number; yield return result; } } |
如果使用得當的話,yield 會變得非常強大。它使得你延遲生成序列中的物件,比如當系統不需要列舉整個集合的時候,可以按需停止。
(譯者注:本文中的專有詞彙基本都使用了中文版 MSDN 中的翻譯)
打賞支援我翻譯更多好文章,謝謝!
打賞譯者
打賞支援我翻譯更多好文章,謝謝!