C# 8 新增小功能

儘管C# 8應該會在今年發佈,並且C# 8.x和9的路線圖也開始形成,但是,微軟正在繼續審查下一個版本的特性。

目標類型表達式

假設我們有A、B和C三種類型,其中類型B和C是類型A的子類型。如果我們使用如下所示的語句,那麼,編譯器無法確定右側要返回的類型。

A a1 = b ?? c;
A a2 = x>0 ? b : c;
A a3 = 	a switch {
    B b => b,
    C c => c,
    _ => throw new System.Exception() 
};

通常情況下,修復該問題需要添加強制轉換,如:

A a1 = (A)b ?? (A)c;
A a2 = x>0 ? (A)b : (A)c;

根據目標類型switch表達式提議,在每種情況下都允許編譯器使用語句(A a1)的左側來決定右側(b ??c)應該返回的類型。該功能還可以用於返回語句(return b ?? c),但不能用於變量(var a1 = b ?? c)。

目前,這個(例3)的模式匹配版本計劃於C# 8.0中提供,其他兩個則於8.x中提供。

允許在解構中使用“default”

根據該提議,這個小功能將允許在初始化元組時使用default關鍵字:

(int i, string s) = default;
(i, s) = default;

過時的屬性

與Visual Basic不同,C#無法把單個getter和setter標記爲過時。相反,只能將屬性作爲整體做這樣的標記。該提議糾正了這種情況。爲了理解這個問題的重要性,請看看Cory Nelson的評論。

就在幾個星期前,我試圖清理一些大量使用get/set屬性的代碼,使其成爲一個更加只讀的初始化的構造函數(ctor-initialized),此時我發現我真希望該特性是這樣的。

4月,該特性從C# 9遷移到了C# 8上。

結構上的只讀成員

當分配給只讀字段或用作in參數時,結構上的方法有個性能小問題。如果我們調用結構上的方法,編譯器首先會生成防禦性副本。儘管這通常不足以產生問題,但是,在用於緊密循環(tight loop)時,細微的低效的確會累積出性能問題。

對於完全不可變的結構,可以標記整個結構爲只讀,這樣可以避免此類情況的發生。然而,出於性能的緣故,很多結構是可變的。

根據只讀示例方法提議,開發人員將能夠把單個方法標記爲只讀。這向編譯器表明,防禦性副本不是必要的,沒有值會被修改。

這和Pure屬性不同,只要只讀方法不修改結構本身的值,那麼就有明顯的副作用。

自動實現屬性的getter將被自動認爲是隻讀的。在某些情況下,setter也可以被標記爲只讀。比如,當屬性值存於字典中而不是直接存入結構本身的時候。

在目前的提議下,引用類型(類和接口)將不會受到該特性的支持。原因有三重:

  • 這麼做,沒有與性能相關的優勢
  • 只讀關鍵字不意味着狀態不會改變,只是不會直接修改對象上的字段。
  • 這是隻讀結構的擴展,沒有等效的只讀類。

查看英文原文:C# 8 More Small Features

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章