C# 的歷史

此文章提供了 C# 語言每個主要版本的歷史。 C# 小組將持續創新並加入新功能。 您可以在ˋ GitHub 上的 dotnet/roslyn 存放庫repository 存放庫中找到詳細語言功能狀態 (包括針對未來版本考慮加入的功能)。

重要

C# 語言中的部分功能仰賴 C#規格定義為「標準程式庫」中的型別和方法。 .NET 平台在許多套件中會提供那些類型與方法。 例外狀況處理便是其中一個例子。 每個 throw 陳述式或運算式都會受到檢查,以確保擲回衍生自 Exception 的物件。 每個 catch 也一樣會受到檢查,以確保攔截到衍生自 Exception 的型別。 每個版本都可能會加入新的需求。 若要在較舊的環境中使用最新的語言功能,可能需要安裝特定的程式庫。 每個特定版本的頁面中會記載這些相依性。 若要知道此相依性的背景,可深入了解語言和程式庫之間的關係

C# 第 12 版

2023 年 11 月發行

C# 12 新增了下列功能:

而且,攔截器 - 已發行為預覽功能

整體而言,C# 12 提供的新功能可讓您在撰寫 C# 程式碼時更有生產力。 可在更多位置使用您已知道的語法。 其他語法可讓相關概念保持一致性。

C# 第 11 版

2022 年 11 月發行

C# 11 中納入了下列功能:

C# 11 推出「泛型數學」和數個支援該目標的功能。 您可以針對所有數字類型,只撰寫一次數值演算法。 有更多功能可讓 struct 類型的運用,變得更加容易,例如必要的成員和自動預設結構。 使用原始字串常值、字串插補中的新行符號,以及 UTF-8 字串常值,都能讓字串的運用更加容易。 檔案本機類型等功能,可讓來源產生器變得更簡單。 最後,清單模式為模式比對加入了更多的支援。

C# 第 10 版

2021 年 11 月發行

C# 10 會將下列功能和增強功能新增至 C# 語言:

還有更多功能以「預覽」模式提供。 若要使用這些功能,您必須將您專案中的 <LangVersion>,設定為 Preview

C# 10 仍持續努力的主題包括,去除程式繁瑣的部分、將資料與演算法分隔開來,以及改善 .NET 執行階段效能等。

其中有許多功能代表鍵入較少的程式碼,即能表達相同的概念。 「記錄結構」合成了許多與「記錄類別」相同的方法。 結構與匿名型別支援 with 運算式。 「全域 using 指示詞」和「檔案範圍命名空間宣告」表示您可以更清楚地陳述相依性和命名空間組織。 「Lambda 改良功能」則可在使用 Lambda 運算式時,能更輕鬆進行宣告。 新的屬性模式和解構的改善,可製作出更簡潔的程式碼。

新的插補字串處理常式和 AsyncMethodBuilder 行為,可以改善效能。 這些語言功能已套用至 .NET 執行階段,以實現 .NET 6 的效能改善。

C# 10 也表明每年度發行 .NET 的節奏將更快。 因為並非所有功能都可以在年度範圍內完成,因此在 C# 10 中可以試用一些「預覽」功能。 「泛型屬性」與「介面中的靜態抽象成員」兩者都可以使用,但這些預覽功能在最終版本之前有可能會有所變更。

C# 第 9 版

2020 年 11 月發行

C# 9 發行時隨附 .NET 5。 這是以 .NET 5 版為目標之所有組件的預設語言版本。 其中包含下列全新功能和增強功能:

C# 9 會持續努力先前版本的三個主題:去除程式繁瑣的部分、將資料與演算法分隔開來,以及在更多地方提供更多模式。

最上層陳述式表示更容易閱讀您的主要程式。 需要繁瑣的程式部分變少:不再需要命名空間、Program 類別和 static void Main()

而推出 records 則能為參考型別提供簡潔的語法,遵循等式的值語意。 您將可使用這些型別,來定義通常定義最基本行為的資料容器。 僅限初始化的 setter 應在記錄中提供非破壞性突變 (with 運算式) 的功能。 C# 9 也新增了共變傳回型別,讓衍生的記錄可以覆寫虛擬方法,並傳回衍生自基底方法傳回型別的類型。

模式比對功能已在數個方面延伸。 數值類型現在支援「範圍模式」。 使用 andornot 模式可結合模式。 為較複雜的模式加入括弧,可以更加清楚:

C# 9 包含新的模式比對改進:

  • 類型模式會符合符合特定類型的物件
  • 括弧化模式會強制執行或強調模式組合的優先順序
  • 連結and模式必須兩個模式均相符
  • 分離or 模式必須其中一個模式相符
  • 否定not模式必須有一種模式不相符
  • 關聯式模式要求輸入小於、大於、小於或等於或大於或等於指定常數

這些模式可擴充模式的語法。 請考慮下列範例:

public static bool IsLetter(this char c) =>
    c is >= 'a' and <= 'z' or >= 'A' and <= 'Z';

使用選擇性括弧,明確 and 的優先順序高於 or

public static bool IsLetterOrSeparator(this char c) =>
    c is (>= 'a' and <= 'z') or (>= 'A' and <= 'Z') or '.' or ',';

最常見的用法之一是 Null 檢查的新語法:

if (e is not null)
{
    // ...
}

這些模式中的任何一種都可以用於允許模式的任何內容:is 模式運算式、switch 運算式、巢狀模式,以及 switch 陳述式的 case 標籤模式。

另一組功能支援以 C# 進行高效能運算:

  • nintnuint 類型會模型化目標 CPU 上的原生大小整數類型。
  • 函式指標提供類似委派的功能,且同時能避免建立委派物件所需的配置。
  • 省略 localsinit 指令可節省一些指令。

效能和 Interop

另一組改善功能可支援「程式碼產生器」新增功能的案例:

  • 模組初始設定式是載入組件時,執行階段所呼叫的方法。
  • Partial 方法支援全新的可存取修飾詞和非 void 傳回型別。 在這些情況下,必須提供實作。

調整和完成功能

C# 9 新增了許多其他小型功能,可提升開發人員無論是撰寫或是讀取程式碼的生產力:

  • 目標型別 new 運算式
  • static 匿名函式
  • 目標型別條件運算式
  • foreach 迴圈的擴充 GetEnumerator() 支援
  • Lambda 運算式可以宣告捨棄參數
  • 屬性可以套用至本機函式

C# 9 版本會持續努力讓 C# 成為可供一般用途的新式程式設計語言。 功能持續支援新式工作負載和應用程式類型。

C# 8.0 版

2019 年 9 月發行

C# 8.0 是第一個專門針對 .NET Core 為目標的主要 C# 版本。 某些功能仰賴新的 Common Language Runtime (CLR) 功能,其他功能則仰賴只有在 .NET Core 中新增的程式庫型別。 C# 8.0 對 C# 語言新增了下列功能和增強功能:

預設介面成員需要 CLR 中的增強功能。 這些功能已新增至 .NET Core 3.0 的 CLR。 範圍和索引,以及非同步串流需要 .NET Core 3.0 程式庫中的新類型。 在編譯器中實作可為 null 的參考型別,會比標註程式庫來提供有關引數和傳回值 null 狀態的語意資訊,來得更加實用。 這些註解也會新增至 .NET Core 程式庫。

C# 7.3 版

2018 年 5 月發行

C# 7.3 版有兩個主要的佈景主題。 其中一個佈景主題提供了使安全的程式碼具有與不安全的程式碼一樣高效能的功能。 第二個佈景主題提供現有功能的累加增強功能。 此版本中也新增了新的編譯器選項。

下列新功能針對安全的程式碼支援較佳效能的佈景主題:

  • 您可以在不釘選的情況下存取固定的欄位。
  • 您可以重新指派 ref 區域變數。
  • 您可以在 stackalloc 陣列上使用初始設定式。
  • 您可以搭配支援模式的任何型別使用 fixed 陳述式。
  • 您可以使用更多泛型條件約束。

已在現有功能中提供下列增強功能:

  • 您可以使用 Tuple 型別測試 ==!=
  • 您可以在更多位置使用運算式變數。
  • 您可以將屬性附加至自動實作屬性的支援欄位。
  • 已改善當引數依 in 不同時的方法解析。
  • 多載解析現在會有較少模稜兩可的情況。

新的編譯器選項:

  • -publicsign,用來啟用組件的開放原始碼軟體 (OSS) 簽署。
  • -pathmap,用來提供來源目錄的對應。

C# 7.2 版

2017 年 11 月發行

C# 7.2 新增了數個小語言功能:

  • stackalloc 陣列上的初始設定式。
  • fixed 陳述式可以搭配支援模式的任何類型使用。
  • 存取固定欄位而不釘選。
  • 重新指派 ref 區域變數。
  • 宣告readonly struct 類型,指示結構不可變,且應以 in 參數傳遞至其成員方法。
  • 對參數新增 in 修飾詞,指定引數將以傳址方式傳遞,但不會受呼叫方法的修改。
  • 對方法的傳回內容使用 ref readonly 修飾詞,指示方法要以傳址方式傳回其值,但不允許寫入該物件。
  • 宣告 ref struct 類型,指示結構類型會直接存取受控記憶體,且一律會配置堆疊。
  • 使用其他泛型條件約束。
  • 非後置具名引數
    • 具名引數之後可以接位置引數。
  • 數值常值中的前置底線:
    • 數值常值的任何列印數字之前,現都可加上前置底線。
  • private protected 存取修飾詞
    • 您可利用 private protected 存取修飾詞,存取相同組件中的衍生類別。
  • 條件 ref 運算式:
    • 條件運算式 (?:) 的結果現在可以是參考。

C# 7.1 版

2017 年 8 月發行

C# 從 C# 7.1 開始,進行了「小數點位數的發行版本」。 此版本也新增了語言版本選擇組態元素、三種新的語言功能和新的編譯器行為。

此版本的新款語言功能包括:

  • asyncMain方法
    • 應用程式的進入點允許使用async修飾詞。
  • default常值運算式
    • 目標類型可以推斷時,可以在預設值運算式中使用預設常值運算式。
  • 推斷的 Tuple 元素名稱
    • 在許多情況下,Tuple 項目的名稱均可從 Tuple 初始化推斷來加以推斷。
  • 泛型型別參數的模式比對
    • 您可以對型別為泛型型別參數的變數使用模式比對運算式。

最後,編譯器有兩個選項 -refout-refonly,可以控制參考組件的產生。

C# 7.0 版

2017 年 3 月發行

C# 7.0 版已隨 Visual Studio 2017 發行。 此版本延續 C# 6.0 的脈絡,有一些先進和酷炫的東西。 下列為部分新功能:

其他功能包括:

所有這些功能都可為開發人員提供一些新的能力,且為開發人員提供了一個機會可撰寫出較以往更加簡潔的程式碼。 重點強調是將變數宣告緊縮為使用 out 關鍵字,以及允許透過 tuple 傳回多個值。 .NET Core 現在以任何作業系統為目標,並堅定地關注雲端和可攜性。 除了提出新功能之外,這些新功能當然也會佔據語言設計人員的想法和時間。

C# 6.0 版

2015 年 7 月發行

Visual Studio 2015 發行版所隨附的 6.0 版,發行了許多可讓 C# 程式設計更具生產力的小功能。 這裡列出其中一些:

其他新功能包括:

  • 索引初始設定式
  • catch/finally 區塊中的 Await
  • 僅限 getter 屬性的預設值

但是,如果您一起看這些功能,您會發現有趣的模式。 在此版本中,C# 開始進行了刻板語言的排除,讓程式碼更加精簡且可讀性更高。 因此,對於喜好乾淨、簡單程式碼的人而言,這個語言版本大幅勝出。

雖然本身不是傳統的語言功能,他們在這個版本中做了另外一件事。 他們將 Roslyn 編譯器發表為服務。 C# 編譯器現在會以 C# 撰寫,您可以使用編譯器,作為程式設計工作的一部分。

C# 5.0 版

2012 年 8 月發行

隨 Visual Studio 2012 發行的 C# 5.0 版,聚焦在語言版本上。 幾乎該版本的所有心血都投入了另一個奠基的語言概念:非同步程式設計的 asyncawait 模型。 以下是主要功能的清單:

呼叫端資訊屬性可讓您輕鬆地擷取您正在執行的內容,而不必依賴大量的未定案反映程式碼。 它在診斷和記錄工作方面有許多用途。

但是 asyncawait 是此版本真正的明星。 當這些功能在 2012 年中推出時,C# 再次改變了遊戲,因為它將非同步深植在語言中,成為頭等參與者。

C# 4.0 版

2010 年 4 月發行

隨附 Visual Studio 2010 發行的 C# 4.0 版引進了一些有趣的新功能:

內嵌 Interop 類型減輕了為應用程式建立 COM Interop 組件的部署階段煩惱。 泛型 covariance 和 contravariance 可讓您有更強大的功能來使用泛型,但它們有點學術,可能最受架構和程式庫作者欣賞。 具名和選擇性參數可讓您消除許多方法多載,並提供方便性。 但這些功能沒有一項能完全改變典範。

主要功能是導入 dynamic 關鍵字。 dynamic 關鍵字為 C# 4.0 版導入在編譯時期型別設定時覆寫編譯器的功能。 藉由使用動態關鍵字,您可以建立類似於動態型別語言 (例如 JavaScript) 的建構。 您可以建立 dynamic x = "a string" 然後將它加六,留給執行階段找出接下來要採取的動作。

動態繫結可能會有錯誤,但也給予您語言內的強大功能。

C# 3.0 版

2007 年 11 月發行

C# 3.0 版在 2007 年晚期和 Visual Studio 2008 一起出現,不過語言功能的完整陣容實際上是在 .NET Framework 3.5 版時齊備。 這個版本標記了 C# 發展的一項重大變更。 它將 C# 樹立為真正令人敬佩的程式設計語言。 讓我們看看此版本的一些主要功能:

回顧以往,許多功能似乎無法避免和分離。 它們全都因為策略的緣故而放在一起。 這個 C# 版本的殺手級功能是查詢運算式,也稱為 Language-Integrated Query (LINQ)。

更細看的話,則會探討出運算式樹狀架構、Lambda 運算式及匿名型別才是建構 LINQ 的基礎。 但無論如何,C# 3.0 呈現了革命性的概念。 C# 3.0 已經開始打下基礎,將 C# 變成混合式的物件導向 / 功能性語言。

具體來說,您現在可以撰寫 SQL 樣式的宣告式查詢,尤其是對集合執行作業。 您不必撰寫 for 迴圈來計算整數清單的平均值,您現在只要用 list.Average() 就能做到。 查詢運算式和擴充方法相組合,能讓整數清單變得更加聰明。

C# 2.0 版

2005 年 11 月發行

讓我們看看 2005 年與 Visual Studio 2005 一起發行的 C# 2.0 中,一些主要功能:

其他 C# 2.0 功能將功能新增至現有功能:

  • Getter/setter 不同協助工具
  • 方法群組轉換 (委派)
  • 靜態類別
  • 委派推斷

雖然 C# 一開始是泛型的物件導向 (OO) 語言,但 C# 2.0 版很急促地改變了。 使用泛型時,型別和方法可以操作任意型別,同時仍然保留型別安全。 例如,List<T> 可讓您具有 List<string>List<int>,並且對那些字串或整數逐一執行型別安全的作業。 使用泛型優於建立衍生自 ArrayListListInt,或針對每個作業從 Object 轉換。

C# 2.0 版帶來了迭代器。 簡單的說,迭代器讓您使用 foreach 迴圈檢查 List (或其他可列舉型別) 中的所有項目。 將迭代器當成語言的頭等部分能大幅增強語言的可讀性,並讓人們能理解程式碼。

C# 1.2 版

2003 年 4 月發行

Visual Studio .NET 2003 隨附 C# 1.2 版。 本版內含對語言的小幅功能改善。 最值得注意的是,自本版開始,當 IEnumerator 實作 IDisposable 時,在 foreach 迴圈產生的程式碼會在 IEnumerator 呼叫 Dispose

C# 1.0 版

2002 年 1 月發行

現在往回看,Visual Studio .NET 2002 隨附發行的 C# 1.0 版,看起來很像 Java。 在其聲明的 ECMA 設計目標當中,它試圖成為「簡單、現代化、一般用途的物件導向語言」。同時,看似 Java 表示它達成了那些早期的設計目標。

但如果您現在回顧 C# 1.0,會覺得有點暈眩。 它缺乏內建的非同步功能和部分圍繞著您視為理所當然的泛型熟練功能。 事實上,它完全缺乏了泛型。 那麼 LINQ 呢? 尚無法使用。 那些新增項目需要好幾年才會出現。

C# 1.0 版看起來與現今相比去除了一些功能。 您會發現自己撰寫一些詳細的程式碼。 但您仍然必須從某處開始。 C# 1.0 版是 Windows 平台上可行的 Java 替代方案。

C# 1.0 的主要功能包含:

文章最初發佈於 NDepend 部落格,感謝 Erik Dietrich 和 Patrick Smacchia。