C# 的歷史
此文章提供了 C# 語言每個主要版本的歷史。 C# 小組將持續創新並加入新功能。 您可以在ˋ GitHub 上的 dotnet/roslyn 存放庫repository 存放庫中找到詳細語言功能狀態 (包括針對未來版本考慮加入的功能)。
重要
C# 語言中的部分功能仰賴 C#規格定義為「標準程式庫」中的型別和方法。 .NET 平台在許多套件中會提供那些類型與方法。 例外狀況處理便是其中一個例子。 每個 throw
陳述式或運算式都會受到檢查,以確保擲回衍生自 Exception 的物件。 每個 catch
也一樣會受到檢查,以確保攔截到衍生自 Exception 的型別。 每個版本都可能會加入新的需求。 若要在較舊的環境中使用最新的語言功能,可能需要安裝特定的程式庫。 每個特定版本的頁面中會記載這些相依性。 若要知道此相依性的背景,可深入了解語言和程式庫之間的關係。
C# 第 11 版
發行日期:2022 年 11 月
C# 11 已新增下列功能:
- 原始字串常值
- 泛型數學支援
- 泛型屬性
- UTF-8 字串常值
- 字串插補運算式中的換行符
- 清單模式
- 檔案本機類型
- 必要成員
- 自動預設結構
- 常數上的模式比
Span<char>
對string
nameof
擴充範圍- Numeric IntPtr
ref
欄位和scoped ref
- 已改善方法群組轉換至委派
- 警告波 7
C# 11 引進泛 型數學 和數個支援該目標的功能。 您可以針對所有數字類型撰寫數值演算法一次。 有更多功能可讓 struct
使用類型變得更容易,例如必要的成員和自動默認結構。 使用字串更容易使用原始字串常值、字串插補中的換行符,以及UTF-8字串常值。 檔案本機類型等功能可讓來源產生器更簡單。 最後,清單模式會新增更多模式比對的支援。
C# 第 10 版
發行於 2021 年 11 月
C# 10 會將下列功能和增強功能新增至 C# 語言:
- 記錄結構
- 結構類型的改善
- 插入字串處理程式
global using
指令- 檔案範圍的命名空間宣告
- 擴充屬性模式
- Lambda 表達式的改善
- 允許
const
插入字串 - 記錄類型可以密封
ToString()
- 改善明確指派
- 在相同的解構中同時允許指派和宣告
- 允許
AsyncMethodBuilder
方法上的屬性 - CallerArgumentExpression 屬性
- 增強型
#line
pragma
預覽模式提供更多功能。 若要使用這些功能,您必須 在項目中設定 <LangVersion>
為 Preview
:
- 本文稍後的 泛型屬性。
- 介面中的靜態抽象成員
C# 10 會繼續處理移除儀式、分隔數據與演算法的主題,以及改善 .NET 運行時間的效能。
許多功能表示您將輸入較少的程式代碼來表達相同的概念。 記錄結構會合成許多與記錄類別相同的方法。 結構與匿名類型支持 表達式。 全域 using 指示詞 和 檔案範圍命名空間宣告 表示您更清楚地表示相依性和命名空間組織。 Lambda 改善 可讓您更輕鬆地宣告使用 Lambda 表達式的位置。 新的屬性模式和解構改善會建立更簡潔的程序代碼。
新的插補字串處理程序和 AsyncMethodBuilder
行為可以改善效能。 這些語言功能已套用在 .NET Runtime 中,以達到 .NET 6 的效能改善。
C# 10 也標誌著 .NET 版本的年度步調。 因為並非所有功能都可以在每年的時間範圍內完成,因此您可以在 C# 10 中嘗試幾個「預覽」功能。 介面中的泛型屬性和靜態抽象成員都可以使用,但這些預覽功能可能會在最終版本之前變更。
C# 第 9 版
發行於 2020 年 11 月
C# 9 已使用 .NET 5 發行。 這是以 .NET 5 版本為目標的任何元件的默認語言版本。 其中包含下列新功能和增強功能:
- 記錄
- 僅限 Init setter
- 最上層陳述式
- 模式比對增強功能:關係型模式和邏輯模式
- 效能和 Interop
- 調整和完成功能
C# 9 會繼續先前版本的三個主題:移除儀式、將數據與演算法分開,以及在更多位置提供更多模式。
最上層語句 表示您的主要程式更容易閱讀。 儀式的需求較少:命名空間、類別 Program
和 static void Main()
都是不必要的。
的引進 records
為參考型別提供簡潔的語法,以遵循值語意進行相等。 您將使用這些類型來定義通常定義最小行為的數據容器。 僅限 Init 的 setter 提供記錄中非破壞性突變 (with
表示式) 的功能。 C# 9 也會新增 covariant 傳回型 別,讓衍生的記錄可以覆寫虛擬方法,並傳回衍生自基底方法傳回型別的類型。
模式 比對 功能已以數種方式擴充。 數值類型現在支援 範圍模式。 模式可以使用、 or
和 not
模式來結合and
。 您可以新增括弧來釐清更複雜的模式:
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# 中的高效能運算:
- 和
nint
nuint
類型會將目標 CPU 上的原生大小整數類型模型化。 - 函式 指標提供類似委派的功能,同時避免建立委派物件所需的配置。
- 您可以省略指示
localsinit
以儲存指示。
效能和 Interop
另一組改善支援程式碼產生器 新增功能的案例 :
調整和完成功能
C# 9 新增許多其他小型功能,可提升開發人員生產力,同時撰寫和讀取程式碼:
- 目標型別
new
運算式 static
匿名函式- 目標型別條件運算式
- 迴圈的
foreach
延伸模組GetEnumerator()
支援 - Lambda 運算式可以宣告捨棄參數
- 屬性可以套用至本機函式
C# 9 版本會繼續工作,讓 C# 保持現代化、一般用途的程式設計語言。 功能可繼續支援新式工作負載和應用程式類型。
C# 8.0 版
發行于 2019 年 9 月
C# 8.0 是第一個主要 C# 版本,特別以 .NET Core 為目標。 某些功能依賴新的 CLR 功能,其他功能則只依賴 .NET Core 中新增的程式庫類型。 C# 8.0 會將下列功能和增強功能新增至 C# 語言:
- 唯讀成員
- 預設介面方法
- 模式比對增強功能 :
- switch 運算式
- 屬性模式
- Tuple 模式
- 位置模式
- Using 宣告
- 靜態區域函式
- 可處置的 ref struct
- 可為 Null 的參考類型
- 非同步資料流
- 索引和範圍
- Null 聯合指派
- Unmanaged 建構類型
- 巢狀運算式中的 Stackalloc
- 增強插入逐字字串
預設介面成員需要 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 發行 點版本 。 此版本新增了 語言版本選取 組態專案、三個新的語言功能和新的編譯器行為。
此版本的新款語言功能包括:
async
Main
方法- 應用程式的進入點允許使用
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 版是語言的焦點版本。 幾乎該版本的所有心血都投入了另一個奠基的語言概念:非同步程式設計的 async
和 await
模型。 以下是主要功能清單:
呼叫端資訊屬性可讓您輕鬆地擷取您正在執行的內容,而不必依賴大量的未定案反映程式碼。 它在診斷和記錄工作方面有許多用途。
但是 async
和 await
是此版本真正的明星。 當這些功能在 2012 年中推出時,C# 再次改變了遊戲,因為它將非同步深植在語言中,成為頭等參與者。 如果您曾經處理過長時間執行的作業,以及回撥網的實作,您可能會愛上這項語言功能。
C# 4.0 版
發行于 2010 年 4 月
使用 Visual Studio 2010 發行的 C# 4.0 版將很難達到 3.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# 版本的殺手功能是查詢運算式,也稱為語言整合式查詢 (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>
,並且對那些字串或整數逐一執行型別安全的作業。 使用泛型比為每個作業建立 ListInt
衍生自 ArrayList
或 轉換的類型 Object
更好。
C# 2.0 版帶來了迭代器。 簡單的說,迭代器讓您使用 foreach
迴圈檢查 List
(或其他可列舉型別) 中的所有項目。 將迭代器當成語言的頭等部分能大幅增強語言的可讀性,並讓人們能理解程式碼。
但 C# 仍繼續追趕 Java。 Java 已經發行了包含泛型和迭代器的版本。 但是,很快就會變更,因為語言會持續朝不同方向發展。
C# 1.2 版
發行于 2003 年 4 月
C# 1.2 版隨附于 Visual Studio .NET 2003。 本版內含對語言的小幅功能改善。 最值得注意的是,自本版開始,當 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。
意見反應
提交並檢視相關的意見反應