微軟C# 8.0中的幾個特性

infoq.com發表於2017-09-06

  概述:可空的引用型別可概括地表述為,引用型別將不再預設可空。因此,開發人員必須使用定義可空值型別的同樣語法“Type?”,顯式地標記一個引用型別為可空。

 

  可空的引用型別(Nullable Reference Types)

  可空的引用型別可概括地表述為,引用型別將不再預設可空。因此,開發人員必須使用定義可空值型別的同樣語法“Type?”,顯式地標記一個引用型別為可空。

  如果將一個空值賦值給一個非可空的引用型別,那麼將會給出一個編譯器警告。與之相類似,從可空型別中讀取也會給出編譯器警告,除非顯式地提前檢查了被質疑的變數是否為空值。因此從理論上講,開發人員需要做的唯一更改就是在程式碼的適當位置標上問號。

  該特性新加了一個語法。該語法針對開發人員明知一個可空變數x並非實際為空值卻無法證明給編譯器的情況。在上述情況下,開發人員現在可以定義x!.Method(),消除編譯器對於潛在空值引用異常的警告。

  非同步流(Async Streams),即foreach async

  非同步流是IEumerable的非同步等價類。C#團隊自2015以來就一直在努力實現非同步流。在經歷了很多爭議後,其語法被定為

foreach await (string s in asyncStream)

  開發人員將使用如下的函式簽名定義一個非同步迭代器:

async IAsyncEnumerable MethodName()

  就像使用一個正常的IEnumerable方法一樣,開發人員可以使用“yield return”以懶方式(Lazy)構建物件流。

  相比於源自響應式擴充套件(Reactive Extensions)的IObservable,使用這一方法的優點在於讓消費者控制流速,這被稱為“Pull模式”。與之相對,IObservable是一種“Push模式”,這意味著生產者可以使用高於消費者所能處理的流速讓流湧向消費者。

  預設介面實現(Default Interface Implementations)

  預設介面實現在本質上是一種有限形式的多重繼承。它允許抽象介面像抽象類一樣,對方法進行完全的定義,只是抽象介面依然不能定義建構函式和欄位。

  需注意,開發人員可以通過使用ConditionalWeakTable在介面上模擬欄位。

  預設介面實現的主要好處是,開發人員可以在不破壞向後相容的條件下,將一個新方法新增到一個已有的介面中。但是這並非是有保證的,因為預設介面只是在可以設計出適合的預設方法時才能工作。

  擴充套件(Extension)

  開發人員可以編寫擴充套件方法,但是不能擴充套件屬性,這是長期以來對C#一直存在的一個問題。事實上,如果使用當前的模式,甚至是不能定義一個擴充套件屬性或事件的。此外,在很多開發人員看來,在靜態類中放置擴充套件方法是“很詭異的”。

  新的設計中新給出了一種稱為“擴充套件”(Extension)的頂層語言構件。例如,如果開發人員想要為自定義的Customer類建立一個擴充套件方法和屬性,可編寫如下程式碼:

extension CustomerExt extends Customer {
    //定義方法和屬性的程式碼。
}

  就介面而言,是不能在擴充套件中定義例項欄位的,但是可以使用ConditionalWeakTable實現模擬。定義靜態欄位也是允許的。

  除了對屬性、事件和操作符過載的擴充套件,C#團隊甚至考慮允許擴充套件建構函式。擴充套件建構函式非常適用於工廠模式(Factory)和物件池場景。

  擴充套件介面(Extension Interfaces)

  C#團隊還考慮了擴充套件介面,即在已有類中新增新介面的能力。但是擴充套件介面將不會成為C# 8中的特性,因為它需要更改底層的執行時。

相關文章