探索 C# 15 中的聯集型別

探索 C# 15 中的聯集型別

Hacker News·4 天前

C# 15 從 .NET 11 Preview 2 開始引入聯集型別,允許開發者宣告一組封閉的型別集,並由編譯器強制執行窮舉模式比對。

背景

微軟在 .NET 11 預覽版中為 C# 15 引入了備受期待的「聯集型別」(Union Types),這項功能允許開發者定義一個變數只能存放固定集合中的某一種型別。透過編譯器強制執行的窮舉模式匹配,C# 試圖在不破壞現有物件導向架構的前提下,提供類似 F# 或 Rust 的函數式編程體驗,解決過去使用介面或基底類別無法達成「封閉集合」限制的問題。

社群觀點

Hacker News 對於 C# 引入聯集型別的討論呈現兩極化反應。支持者認為這填補了 C# 長期以來在型別系統上的空缺,特別是解決了 API 回傳值不確定性(例如回傳結果或異常)的痛點。許多開發者指出,過去為了達成類似效果,必須依賴第三方函式庫或複雜的類別階層,現在原生支援不僅能提升程式碼的可讀性,還能讓編譯器在編譯時期就抓出未處理的邊界案例,大幅減少執行時期的錯誤。

然而,反對與擔憂的聲音也相當顯著。部分開發者批評 C# 正在變成一個「大雜燴」語言,不斷從 F# 或 Rust 搬運功能,卻缺乏整體的設計願景。有評論者認為,C# 頻繁增加語法糖(如集合字面量、主要建構子等)導致語言變得過於複雜,對初學者而言學習曲線急劇上升,甚至可能演變成像 C++ 那樣「每個人只使用其中一個子集」的混亂局面。此外,一些資深 F# 使用者感嘆,雖然 C# 吸收了函數式特性,但其本質仍受限於 .NET 的物件導向框架,無法達到像純函數式語言那樣的簡潔與優雅,反而讓 C# 顯得臃腫且失去方向。

關於技術細節的爭論則集中在「名義聯集」(Nominal Unions)與「即時聯集」(Ad-hoc Unions)的差異。C# 15 採用的方案要求開發者必須先宣告一個具名的聯集型別,這與 TypeScript 那種隨手定義的結構化聯集不同。部分開發者對此感到失望,認為這限制了靈活性;但也有人反駁,明確的型別定義有助於大型專案的維護與文件化,避免像 TypeScript 那樣因過度靈活而產生難以追蹤的「型別義大利麵」。

此外,社群也討論到 .NET 生態系的演變。有觀點認為微軟將重心完全傾斜至 C#,導致 F# 逐漸邊緣化,甚至讓 CLR 實質上變成了「C# 執行環境」。儘管如此,多數評論者仍認同 C# 作為通用語言的地位,其在效能優化(如 Native AOT)與跨平台支援上的進步是有目共睹的。聯集型別的加入,被視為 C# 在現代化道路上邁出的重要一步,儘管它帶來的語法複雜度確實引發了關於語言純粹性的深刻反思。

延伸閱讀

在討論過程中,開發者們提到了幾個與聯集型別及 .NET 發展相關的深度資源。首先是 Midori 作業系統計畫,這是微軟過去嘗試用託管程式碼撰寫作業系統的實驗,對於理解 C# 效能與記憶體管理的極限極具參考價值。其次是 Npgsql 專案,它證明了在 .NET 生態中,PostgreSQL 等非微軟原生資料庫同樣能獲得一等公民等級的支援。最後,針對 C# 15 聯集型別的底層實作細節,社群推薦關注相關的語言規格提案,特別是關於非裝箱(non-boxing)存取模式的設計,這對於追求極致效能的開發者至關重要。

https://devblogs.microsoft.com/dotnet/csharp-15-union-types/