1. 程式人生 > >C# 9.0 新特性之目標型別推導 new 表示式

C# 9.0 新特性之目標型別推導 new 表示式

閱讀本文大概需要 2 分鐘。

呼~~,每次過完一個週末,寫作就失去了動力,一兩天才能緩過來。儘管如此,還是要堅持寫好每一篇文章的。寧缺毋濫嘛,寧願發文的頻率低一點,也要保證文章的質量,至少排版不能差,行文要流暢,錯別字不能有。 關於**型別推導**想必大家都很熟悉,它是在 var 關鍵字引入的時候引入 C# 的。 ```cs var i = 10; var u = new User(); ``` 編譯器會通過右邊的字面量自動推導左邊變數的型別,這種推導方式可以歸納為:從上下文右邊推匯出左邊的型別。我們不妨把它稱為**源型別推導**(Source-typed inferring,參考 Target-typed 自創的術語)。 相應的,有源型別推導就有**目標型別推導** (Target-typed inferring),它是指從上下文左邊推匯出右邊的型別。比如陣列的初始化和 Lambda 表示式常常是目標型別推導的表示式。舉個例子: ```cs // 沒有使用型別推導 string[] s = new string[] { "a", "b" }; // 目標型別推導(左推右) string[] s = new { "a", "b" }; string[] s = new [] { "a", "b" }; // 沒有使用型別推導 Users.FirstOrDefault(u => u.id = 123); // 目標型別推導(左推右) Users.FirstOrDefault(u => u.id = 123); ``` 這次在 C# 9 中,增加了使用者定義型別 new 表示式的目標型別推導,即通過上下文左邊自動推導 new 表示式的型別,從而在使用 new 構造時省略型別的指定,請看示例: ```cs // C# 9 之前 Point p = new Point(3, 5); // C# 9 Point p = new (3, 5); ``` 除此之外,C# 9 也增加了操作符 `??` 和 `?:` 的目標型別推導支援。之前這兩個操作符必須要求兩邊的操作物件都是相同的型別,否則會編譯報錯。而在 C# 9 中,只要目標型別是操作物件共同的基類就不再會編譯報錯了,比如: ```cs // Student 和 Customer 擁有共同的父類 Person Person person = (Person)(student ?? customer); // C# 9 之前 Person person = student ?? customer; // C# 9 // 可空型別,0 和 null 都可以隱式轉換為 int? 型別 int? result = b ? 0 : (int?)null; // C# 9 之前 int? result = b ? 0 : null; // C# 9 ``` 其實本文的核心就一句程式碼: ```cs Point p = new (3, 5); ``` 卻一不小心囉嗦了這麼一堆。但講真,學習新的知識不是要死記硬背,而要學會歸類推理,舉一反三,經常思考,最好能形成自己的一種思維習慣,這樣學習才會變成一件水到渠成的事。多看我的文章,希望你能學到的不僅僅是生硬的程式設計知識點,也希望我的行文風格和思維習慣對你有所啟發。