C# 10 的最新功能
C# 10 會將下列功能和增強功能新增至 C# 語言:
- 記錄結構
- 結構類型的改善
- 插補字串處理常式
global using
指示詞- 檔案範圍的命名空間宣告
- 擴充屬性模式
- Lambda 運算式的改善
- 允許
const
插補字串 - 記錄類型可以密封
ToString()
- 明確指派的改善
- 在相同解構中允許指派和宣告
- 在方法上允許
AsyncMethodBuilder
屬性 - CallerArgumentExpression 屬性
#line
pragma 功能強化- 警告波 6
.NET 6 上支援 C# 10。 如需詳細資訊,請參閱 C# 語言版本控制。
您可以從 .NET 下載頁面下載最新 .NET 6 SDK。 您也可以下載 Visual Studio 2022,其包含 .NET 6 SDK。
注意
歡迎您提供這些功能的相關意見反應。 如果您發現上述這些新功能的任何功能,請在 dotnet/roslyn 存放庫中建立新問題。
記錄結構
您可以使用 record struct
或 readonly 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
方法。 sealed
ToString
可確保所有衍生的記錄類型都使用通用基底記錄類型中定義的 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
陳述式中的 true
或 false
陳述式中存取變數,以及 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 為基礎範例的功能規格。