C# 10 的最新功能

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

.NET 6 上支援 C# 10。 如需詳細資訊,請參閱 C# 語言版本控制

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

注意

歡迎您提供這些功能的相關意見反應。 如果您發現上述這些新功能的任何功能,請在 dotnet/roslyn 存放庫中建立新問題

記錄結構

您可以使用 record structreadonly record struct 宣告來宣告實值型別記錄。 您現在可以釐清 record 是具有 record class 宣告的參考型別。

結構類型的改善

C# 10 引進下列與結構類型相關的改善:

  • 您可以在結構類型中宣告執行個體無參數建構函式,並在其宣告中初始化執行個體欄位或屬性。 如需詳細資訊,請參閱結構型別一文中的結構初始化和預設值一節。
  • with 運算式的左側運算元可以是任何結構類型或匿名 (參考) 類型。

插補字串處理常式

您可以建立類型,以從插補字串運算式建置產生的字串。 .NET 程式庫會在許多 API 中使用此功能。 您可以遵循此教學課程來建置一個。

全域 using 指示詞

您可以將 global 修飾元新增至任何 using 指示詞,以指示編譯器將指示詞套用至編譯中的所有來源檔案。 這通常是專案中的所有來源檔案。

檔案範圍的命名空間宣告

您可以使用 namespace 宣告的新形式來宣告後續的所有宣告都是宣告命名空間的成員:

namespace MyNamespace;

此新語法可節省 namespace 宣告的水平和垂直空間。

擴充屬性模式

從 C# 10 開始,您可以參考屬性模式內的巢狀屬性或欄位。 例如,表單的模式

{ Prop1.Prop2: pattern }

在 C# 10 和更新版本中有效,且相當於

{ Prop1: { Prop2: pattern } }

在 C# 8.0 和更新版本中有效。

如需詳細資訊,請參閱擴充屬性模式功能提案注意事項。 如需屬性模式的詳細資訊,請參閱模式一文中的屬性模式一節。

Lambda 運算式改善

C# 10 包含 Lambda 運算式處理方式的許多改善:

  • Lambda 運算式可能有自然類型,其中編譯器可以從 Lambda 運算式或方法群組推斷委派類型。
  • 當編譯器無法推斷傳回類型時,Lambda 運算式可能會宣告傳回類型。
  • 屬性可以套用至 Lambda 運算式。

這些功能讓 Lambda 運算式更類似方法和本機函式。 它們可讓您更輕鬆地使用 Lambda 運算式,而不需要宣告委派類型的變數,而且更順暢地與新的 ASP.NET Core 最小 API 搭配運作。

常數差補字串

在 C# 10 中,如果所有預留位置本身都是常數字串,就可以使用字串插補來初始化 const 字串。 建置在應用程式中使用的常數字串時,字串插補可以建立更容易讀取的常數字串。 預留位置運算式不能是數值常數,因為這些常數會在執行階段轉換成字串。 目前的文化特性可能會影響其字串表示。 在 const 運算式上的語言參考中深入了解。

記錄類型可以密封 ToString

在 C# 10 中,當您在記錄類型中覆寫 ToString 時,可以新增 sealed 修飾元。 密封 ToString 方法可防止編譯器為任何衍生記錄類型合成 ToString 方法。 sealedToString 可確保所有衍生的記錄類型都使用通用基底記錄類型中定義的 ToString 方法。 您可以在記錄文章中深入了解此功能。

相同解構中的指派和宣告

此變更會移除舊版 C# 的限制。 先前,解構可以將所有值指派給現有的變數,或初始化新宣告的變數:

// Initialization:
(int x, int y) = point;

// assignment:
int x1 = 0;
int y1 = 0;
(x1, y1) = point;

C# 10 會移除此限制:

int x = 0;
(x, int y) = point;

改善明確指派

在 C# 10 之前,有明確指派和 Null 狀態分析產生的警告為誤判的許多案例。 這些通常牽涉到布林值常數的比較、只在 if 陳述式中的 truefalse 陳述式中存取變數,以及 Null 聯合運算式。 這些範例在舊版 C# 中產生警告,但不在 C# 10 中:

string representation = "N/A";
if ((c != null && c.GetDependentValue(out object obj)) == true)
{
   representation = obj.ToString(); // undesired error
}

// Or, using ?.
if (c?.GetDependentValue(out object obj) == true)
{
   representation = obj.ToString(); // undesired error
}

// Or, using ??
if (c?.GetDependentValue(out object obj) ?? false)
{
   representation = obj.ToString(); // undesired error
}

此改善的主要影響是明確指派和 Null 狀態分析的警告更精確。

在方法上允許 AsyncMethodBuilder 屬性

在 C# 10 和更新版本中,除了為會傳回類似工作類型的所有方法指定方法產生器類型之外,您還可以為單一方法指定不同的非同步方法產生器。 自訂非同步方法產生器可啟用進階效能微調案例,其中指定的方法可能從自訂產生器受益。

若要深入了解,請參閱編譯器所讀取的屬性一文中的 AsyncMethodBuilder 一節。

CallerArgumentExpression 屬性診斷

您可以使用 System.Runtime.CompilerServices.CallerArgumentExpressionAttribute 來指定參數,編譯器會以另一個引數的文字表示取代。 此功能可讓程式庫建立更具體的診斷。 下列程式碼會測試條件。 如果條件為 false,則例外狀況訊息會包含傳遞至 condition 的引數文字表示:

public static void Validate(bool condition, [CallerArgumentExpression("condition")] string? message=null)
{
    if (!condition)
    {
        throw new InvalidOperationException($"Argument failed validation: <{message}>");
    }
}

您可以在語言參考一節中的呼叫端資訊屬性一文中深入了解此功能。

增強的 #line pragma

C# 10 支援 #line pragma 的新格式。 您可能不會使用新的格式,但您會看到其效果。 增強功能可在網域特定語言 (DSL) (例如 Razor) 中實現更精細的輸出。 Razor 引擎會使用這些增強功能來改善偵錯體驗。 您會發現偵錯工具可以更精確地反白顯示您的 Razor 來源。 若要深入了解新語法,請參閱語言參考中的前置處理器指示詞一文。 您也可以閱讀以 Razor 為基礎範例的功能規格