共用方式為


C# 14 的新功能

C# 14 包含下列新功能。 您可以使用最新的 Visual Studio 2022 版本或 .NET 10 SDK 來試用這些功能:

.NET 10 支援 C# 14。 如需詳細資訊,請參閱 C# 語言版本設定。

您可以從 .NET 下載頁面下載最新的 .NET 10 SDK。 您也可以下載 Visual Studio 2022,其中包含 .NET 10 SDK。

新功能會在公開預覽版本中提供時,新增至 [C# 的新功能] 頁面。 工作集區段在Roslyn 功能狀態頁面上,追蹤即將推出的功能何時合併到主要分支。 本文最後更新於 .NET 10 Preview 1。

您可以在有關 重大變更的文章中找到 C# 14 中導入的任何重大變更。

備註

我們對這些功能的意見反應有興趣。 如果您發現上述任何新功能的問題,請在 dotnet/roslyn 存放庫中建立新的問題

擴充成員

C# 14 會新增語法來定義 擴充成員。 新的語法可讓您除了擴充方法之外,還宣告 擴充屬性 。 您也可以宣告延伸型別而非型別實例的擴充成員。 換句話說,這些新的擴充成員可以作為您擴充類型的靜態成員存在。 下列程式代碼範例示範您可以宣告的不同擴充成員類型範例:

public static class Enumerable
{
    // Extension block
    extension<TSource>(IEnumerable<TSource> source) // extension members for IEnumerable<TSource>
    {
        // Extension property:
        public bool IsEmpty => !source.Any();
        // Extension indexer:
        public TSource this[int index] => source.Skip(index).First();

        // Extension method:
        public IEnumerable<TSource> Where(Func<TSource, bool> predicate) { ... }
    }

    // extension block, with a receiver type only
    extension<TSource>(IEnumerable<TSource>) // static extension members for IEnumerable<Source>
    {
        // static extension method:
        public static IEnumerable<TSource> Combine(IEnumerable<TSource> first, IEnumerable<TSource> second) { ... }

        // static extension property:
        public static IEnumerable<TSource> Identity => Enumerable.Empty<TSource>();
    }
}

第一個擴充區塊中的成員會被呼叫,就像是 IEnumerable<TSource> 的實例成員一樣,例如 sequence.IsEmpty。 第二個擴充區塊中的成員會被呼叫,就像是 IEnumerable<TSource> 的靜態成員一樣,例如 IEnumerable<int>.Identity

您可以在程式設計指南中閱讀延伸模組成員的文章、關鍵詞上的extension語言參考文章,以及新延伸模組成員功能的功能規格,以深入瞭解詳細數據。

field 關鍵詞

使用field令牌可讓您撰寫屬性存取方法主體,而無需宣告明確的後設欄位。 令牌 field 被替換為編譯器自動生成的備用欄位。

例如,先前,如果您想要確保 string 屬性無法設定為 null,則必須宣告支援字段並實作這兩個存取子:

private string _msg;
public string Message
{
    get => _msg;
    set => _msg = value ?? throw new ArgumentNullException(nameof(value));
}

您現在可以將程式代碼簡化為:

public string Message
{
    get;
    set => field = value ?? throw new ArgumentNullException(nameof(value));
}

您可以為以欄位支援的屬性,定義單個或雙個存取子的主體。

當類型中包含名為 field 的符號時,可能會導致程式碼中斷或造成閱讀上的混淆。 您可以使用 @fieldthis.field 來消除關鍵字 field 與識別符之間的混淆,也可以重新命名目前的 field 符號,以提供更佳的區別。

如果您嘗試此功能並有意見反應,請在存放庫中的功能問題csharplang上發表評論。

field 內容關鍵詞位於 C# 13 中作為預覽功能。

隱含範圍轉換

C# 14 引入了對語言中System.Span<T>System.ReadOnlySpan<T>的一流支援。 此支援牽涉到新的隱含轉換,允許使用這些類型進行更自然的程序設計。

Span<T>ReadOnlySpan<T> 在 C# 和運行時間中有許多主要方式使用。 其引進可改善效能,而不會造成安全性風險。 C# 14 可辨識關聯性,並支援ReadOnlySpan<T>Span<T>T[]之間的一些轉換。 範圍類型可以是擴充方法接收者、與其他轉換組合,以及協助進行泛型類型推斷情境。

您可以在語言參考一節的 內建類型 一文中找到隱含範圍轉換的清單。 您可以閱讀 第一類範圍類型的功能規格,以深入瞭解詳細數據。

未系結泛型型別和 nameof

從 C# 14 開始,nameof 的參數可以是未綁定的泛型類型。 例如,nameof(List<>) 結果為 List。 在舊版的 C# 中,只能使用 關閉的泛型型別,例如 List<int>,來傳回 List 名稱。

具有修飾詞的簡單 Lambda 參數

您可以新增參數修飾詞,例如 scopedrefinoutref readonly 至 Lambda 運算式參數,而不需指定參數類型:

delegate bool TryParse<T>(string text, out T result);
// ...
TryParse<int> parse1 = (text, out result) => Int32.TryParse(text, out result);

先前,只有在參數宣告包含參數的類型時,才允許新增任何修飾詞。 上述宣告需要所有參數的類型:

TryParse<int> parse2 = (string text, out int result) => Int32.TryParse(text, out result);

修飾子 params 仍然需要具體類型的參數列表。

您可以在 C# 語言參考中的 Lambda 運算式 一文中深入瞭解這些變更。

更多次要成員

您現在可以將 實例建構函式事件 宣告為 部分成員

部分建構函式和部分事件必須包含一個 定義宣告 和一個 實作宣告

只有部分建構函式的實作宣告可以包含建構函式初始化運算式: this()base()。 只有一個部分類型宣告可以包含主要建構函式語法。

部分事件的實作宣告必須包含 addremove 存取子。 定義聲明宣告一個類似欄位的事件。

使用者定義的複合指派

您可以在 使用者定義複合指派的功能規格中深入瞭解。

空值條件式指派

Null 條件式成員存取運算符 ?.?[]現在可以在指派或複合指派的左側使用。

在 C# 14 之前,您需要先對變數進行 Null 檢查,再指派給 屬性:

if (customer is not null)
{
    customer.Order = GetCurrentOrder();
}

您可以使用運算子來簡化上述程式代碼 ?.

customer?.Order = GetCurrentOrder();

只有在左邊不是 Null 時,才會評估運算子的 = 右側。 如果 customer 為 null,則程式代碼不會呼叫 GetCurrentOrder

除了指派之外,您還可以使用 Null 條件式成員存取運算符搭配複合指派運算符 (+=-=等)。 不過,不允許遞增和遞減 ++--

您可以在語言參考文章中深入瞭解 條件成員存取Null 條件式指派的功能規格。

另請參閱