微軟提議在C# 7中為引用增加選項類型
英文原文:A Proposal to Add Option Types for References to C# 7
微軟 C# 語言的項目經理 Mads Torgersen,最近提議在C# 7 中引入可為選項類型(option types)的引用類型。加入選項類型能讓 C# 語言變得更安全,正如 Torgersen 所說,在 C# 里,因為任一引用類型都能引用一個空值,從而導致了空引用異常的泛濫成災,而使用選項類型能減少空引用異常的產生。
C#已經對 nullable 值類型提 供了支持,即對基于 struct 的已提供了支持,但不支持基于 class 的引用類型。對一門現存的已然成熟的編程語言事后加入選項類型,這其中存在著巨大的復雜性,出于這一原因,Torgersen 不打算建立一套“滴水不漏的”機制,而是在檢測到代碼可能存在解引用空值的時候發出警告信息。
新的提議方案對一個現有的引用類型T有如下約定:
- T 用來表示一個非 nullable 類型;
- T?用來表示一個 nullable 引用類型;
- 在以下情況下,編譯器將發出告警信息:
-
一個 nullable 的
T?類型被解引用或者轉化為一個非
nullable 類型; - 將 null/default (T)賦值給非 nullable T 類型變量;
- 流分析檢測到一個 nullable 引用很可能不再是空值;
- 構造函數在返回前未對非 nullable 引用進行賦值;
- 構造函數使用尚未賦值的非 nullable 引用。
另一方面,當一個非 nullable 數組在進行初始化時,無法確保其中為 null 的數組成員不被保留下來。
使用空條件操作符(null-conditional operator)?.,可參考介紹C# 6,將產生以下效果:
string s; string? ns = SomeStringMaybe ();s = ns; // emits warning if (ns != null) { s = ns; } // ok
WriteLine (ns.Length); // emits warning WriteLine (ns?.Length); // ok</pre>
盡管使用這種新設計出的方法不用改動任何 的現有代碼,但該方法仍可能對編譯器的行為產生潛在的影響,因為在當前的 C# 里,T實際上用來表示一個 nullable 類型。因此,Torgersen 說,需要另外再新增一套機制來關閉告警信息,用于確保在跨 C# 版本和程序集下的編譯兼容性。需要重點聲明的是,當所賦的值為 null 時,若編譯器只產生告警信息,那么C# 7 仍將會允許一個非 nullable 類型T包含 null 類型,這主要是出于對程序集兼容性的考慮。這也使得C# 7 表現得與其他編程語言大相徑庭,比如 Swift option types 和 Haskell Maybe,在 Swift 和 Haskell 中,選項類型可被視為對基本類型的一種封裝(實際上,在 Swift 里選項類型就是泛型類型,在 Haskell 里就是 monad)。
從通告的評論來看,人們對微軟的提議反應不一。有些人擔心在重新定義了類型T為非 nullable 之后,現存的 C# 代碼會產生大量的對他們來說毫無意義的告警信息。還有些人認為應該用T!或者其他不同于基本類型T的表示方式來表征非 nullable 類型,基本類型T繼續用來表示 nullable 類型。
微軟的提議方法沒有讓任何已有的代碼受益,應對其進行重構以使其有助于代碼的 non-nullability。另外有部分人支持該提議,并表示自己更喜歡這種“嚴謹的”模式,在這種模式下,空值經由 option<T>或其它等效結構被有效地封裝了起來。
來自: InfoQ本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!