C# 版本特性一覽

2023-06-06 15:07:16

前言

使用 C# 作為開發語言已經 15 個年頭了,受惠於 C# 的不斷更新,伴隨著大量的新特性與大量語法糖,讓我更加容易寫出簡潔、高效的程式碼。日常中大量特性早已信手拈來,當然從未嘗試過的特性更是難以盡數,但是每每回憶程式碼中的特性究竟是哪個版本引入的,卻頗為含糊。索性簡單整理記錄下來,用以備忘,進而能夠更精確地根據想使用的特性確定程式需要的 Framework 版本。
儘管參考了微軟的官方檔案,但所列特性難免基於我所接觸使用到的狹隘範圍,用中括號附上短評(如【我是短評】),用以提示,希望不至於畫蛇添足吧。

版本一覽

C# 1.0

釋出日期:2002 年 1 月
一切的開始,由於我是從 2.0 開始接觸 C# 的,在此不贅述該版本了,只能說 C# 的起點不低,從 Java 轉過來上手很快,兼具 C 語族的語法特點,同時又很有 Delphi 味,簡直夢幻開局。

C# 1.2

釋出日期:2003 年 4 月
從此版本開始,當 IEnumerator 實現 IDisposable 時,foreach 迴圈中生成的程式碼會在 IEnumerator 上呼叫 Dispose。【剛剛知道還有這特性】

C# 2.0

釋出日期:2005 年 11 月
和 Visual Studio 2005 一起釋出。看看這些金光閃閃的特性吧:

  • 泛型
  • 分部型別【partial 關鍵字】
  • 匿名方法【利用 delegate 運運算元】
  • 可為空的值型別【Nullable<T>T?
  • 迭代器【yield return 語句】
  • 協變和逆變【這時候還不支援泛型介面和委託】
  • getter/setter 單獨可存取性
  • 靜態類

C# 3.0

釋出日期:2007 年 11 月
C# 3.0 和 Visual Studio 2008 一起釋出於 2007 年下半年,但完整的語言功能是在 .NET Framework 3.5 版中釋出的。如果說 2.0 時期是分庭抗禮,那麼到了 3.0 就真的是一騎絕塵,諸多特性完美地結合在一起。儘管我習慣用 Lambda 表示式與鏈式呼叫來寫 LINQ ,但是查詢表示式寫法的 LINQ 實在是太驚豔了。

  • 自動實現的屬性【{ get; set; } 寫法】
  • 匿名型別【new { Foo = 108, Bar = "Hello" } 寫法】
  • 查詢表示式【from foo select bar where baz 寫法】
  • Lambda 表示式
  • 表示式樹
  • 擴充套件方法
  • 隱式型別本地變數【var 關鍵字】
  • 分部方法【partial 關鍵字可以作用在方法上,沒用過該特性】
  • 物件和集合初始值設定項【Foo foo = new Foo { Bar = "Hello" } 寫法】
  • WPF、WCF、WF

C# 4.0

釋出日期:2010 年 4 月
C# 版本 4.0 隨 Visual Studio 2010 一起釋出,引入了一些小改進。

  • 動態繫結【dynamic 關鍵字,不在編譯時檢查型別,而是在執行時評估。】
  • 命名實參和可選實參【可以少些一些方法過載了】
  • 泛型協變和逆變【完全體,但一般只有底層類庫設計者需要考慮這玩意】
  • 嵌入的互操作型別【沒什麼存在感】
  • System.Threading.Tasks 名稱空間【更方便的執行緒操作及並行處理】
  • System.Tuple
  • 現有類的新方法【例如 String.IsNullOrWhiteSpaceStopwatch.RestartStringBuilder.Clear 等等】
  • 現有方法的新過載【例如 String.Join 方法新增了可以連線 IEnumerable<T> 集合的成員的新過載。】
  • Managed Extensibility Framework (MEF)【動態載入,實現外掛系統的好幫手】
  • ASP.NET MVC

C# 5.0

釋出日期:2012 年 8 月
C# 版本 5.0 隨 Visual Studio 2012 一起釋出。.NET Framework 4.5、4.5.1、4.5.2 基本上就是一系列更新和優化,新東西很少。

  • 非同步成員【asyncawait,版本之子。】
  • 呼叫方資訊特性【CallerMemberName 等,方便確定呼叫方資訊。】

C# 6.0

釋出日期:2015 年 7 月
版本 6.0 隨 Visual Studio 2015 一起釋出,釋出了很多使得 C# 程式設計更有效率的小功能。對應 .NET Framework 4.6、4.6.1、4.6.2。.NET Core 出現了,好訊息是 .NET 開放原始碼了,壞訊息是微軟開始折騰,從這開始語法糖多得齁嗓子。得益於諸多新特性,程式碼變得簡短了,但是引入了很多新符號,心智負擔加重了。「Null 條件運運算元」、「字串內插」、「nameof 表示式」是我比較喜歡的特性。

  • 靜態匯入【using static 指令命名了一種型別,無需指定型別名稱即可存取其靜態成員和巢狀型別。】
  • 異常篩選器【catch (ExceptionType [e]) when (expr)
  • 自動屬性初始化表示式【public string Foo { get; set; } = string.Empty;
  • 表示式主體定義【例如:public override string ToString() => $"{foo} {bar}";
  • Null 條件運運算元【成員存取?. 或元素存取?[]
  • 字串內插【$"{foo} {bar}"
  • nameof 表示式【nameof(Foo)

C# 7.0

釋出日期:2017 年 3 月
C# 7.0 版已與 Visual Studio 2017 一起釋出。 此版本繼承和發展了 C# 6.0。對應 .NET Framework 4.7、4.7.1、4.7.2。「out 變數」、「模式匹配」是我比較喜歡的特性。後續的 C# 7.1、7.2、7.3 基本都在為新特性添磚加瓦。明顯開始和別的語言抄來抄去,當然我們一般都稱為「借鑑」。

  • out 變數【if (Int32.TryParse(foo, out int bar)) Console.WriteLine($"Converted '{foo}' to {bar}");
  • 元組【(double Foo, int Bar) t2 = (4.5, 3);
  • 模式匹配
  • 本地函數【內部函數,讓我想起了 Delphi】
  • ref 區域性變數【指標既視感】
  • 棄元【(_, _, foo) = bar.baz();,配合元組,你可以給,但我可以不要。】

C# 8.0

釋出日期:2019 年 9 月
C# 8.0 版是專門面向 .NET C# Core 的第一個主要 C# 版本。特性列了一大篇,實在是沒法看了,下面就沒有一一列舉,指令碼語言味兒越來越重,各種操作符、關鍵字更是玩出花來,心智負擔越發沉重了。除了模式匹配,別的特性完全不想碰。

  • 預設介面方法【抽象也能順便帶點兒實現,腦抽特性】
  • 模式匹配增強功能【來嘛,有點學不過來了啊】
  • Null 合併賦值【??=
  • 後面懶得列了……

C# 9

釋出日期:2020 年 11 月
C# 9 隨 .NET 5 一起釋出。 它是面向 .NET 5 版本的任何程式集的預設語言版本。對於既存特性進行了梳理與調整,然後引入了一大堆新特性,這是有 KPI 壓力嗎?老特性千萬別給我搞沒了,新特性我也保證不碰,咱們心照不宣吧。

  • 記錄【record 關鍵字,唯讀資料類語法糖】
  • 僅限 Init 的資源庫【public int Foo { get; init; } ,唯讀資料類語法糖之二】
  • 頂級語句【為了少寫點程式碼微軟也是拼了】
  • 模式匹配增強功能【繼續增強……】
  • 函數指標【圖窮匕見,高效能運算這一塊與我似乎沒有交集】
  • 後面懶得列了……

C# 10

釋出日期:2021 年 11 月
C# 10 繼續致力於刪除不必要的模式、將資料與演演算法分離以及提高 .NET 執行時的效能等主題。特性列表又是像寫小說一樣長,行吧,你開心就好。

  • 這次我一個也不想列……

C# 11

釋出日期:2022 年 11 月
和前面比起來稍微節制了一點兒,優化了數學計算和字串處理,模式匹配不用說,給我增強!

  • 泛型數學支援【不懂】
  • UTF-8 字串字面量【"foo"u8】
  • 必需的成員【required 修飾符,KPI 味太濃了】
  • 其他的不列了……

後記

可以說從 6.0 開始就不幹正事兒了,有實際意義的特性越來越少,效能增強、安全性加強什麼的是值得肯定的,但是加的這一堆特性真是有點缺乏節制,我寧可在 11 的環境下寫著 6 的程式碼。人家是「人生苦短」,我看微軟是「只嫌命長」啊。