儘管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