C# 13 的新功能
C# 13 包含下列新功能。 您可以使用最新的 Visual Studio 2022 版本或 .NET 9 SDK來嘗試這些功能:
-
params
集合 -
新的
lock
類型和語意。 -
新的逸出序列 -
\e
。 - 方法群組自然類型改善
- 物件初始化表達式中的隱含索引器存取
-
在反覆運算器和異步方法中啟用
ref
局部變數和unsafe
內容 -
啟用
ref struct
類型以實作介面。 - 允許 ref 結構類型 做為泛型中型別參數的自變數。
-
部分屬性和索引器 現在可在
partial
類型中使用。 - 多載解析優先順序 可讓函式庫作者指定一個多載優於其他多載。
從 Visual Studio 17.12 開始,C# 13 會以預覽功能的形式包含 field
內容關鍵詞。
C# 13 受到 .NET 9的支持。 如需詳細資訊,請參閱 C# 語言版本設定。
您可以從 .NET 下載頁面下載最新的 .NET 9 SDK。 您也可以下載 Visual Studio 2022 ,其中包含 .NET 9 SDK。
新功能會在公開預覽版本中提供時,新增至 [C# 的新功能] 頁面。 roslyn 功能狀態頁面 追蹤即將推出的功能合併至主要分支時,工作集 區段。
您可以在我們的文章中找到 C# 13 引入的任何重大變更,詳見 重大變更。
注意
我們對這些功能的意見反應有興趣。 如果您發現任何上述新功能的問題,請在 dotnet/roslyn 存放庫中建立 新問題。
params
集合
params
修飾詞不僅限於陣列類型。 您現在可以將 params
用於任何可辨識的集合類型,包括 System.Span<T>、System.ReadOnlySpan<T>,以及實作 System.Collections.Generic.IEnumerable<T> 且包含 Add
方法的類型。 除了具體類型,也可以使用介面 System.Collections.Generic.IEnumerable<T>、System.Collections.Generic.IReadOnlyCollection<T>、System.Collections.Generic.IReadOnlyList<T>、System.Collections.Generic.ICollection<T>和 System.Collections.Generic.IList<T>。
使用介面類型時,編譯程式會合成所提供自變數的記憶體。 您可以在 params
集合的功能規格中深入瞭解。
例如,方法宣告可以將範圍宣告為 params
參數:
public void Concat<T>(params ReadOnlySpan<T> items)
{
for (int i = 0; i < items.Length; i++)
{
Console.Write(items[i]);
Console.Write(" ");
}
Console.WriteLine();
}
新的鎖定物件
.NET 9 運行時間包含線程同步處理的新類型,System.Threading.Lock 類型。 此類型透過其 API 提供更佳的線程同步處理。
Lock.EnterScope() 方法會進入專有範圍。 傳回的 ref struct
支援 Dispose()
模式來退出獨佔範圍。
C# lock
語句會辨識鎖定的目標是否為 Lock
物件。 如果是,它會使用更新的 API,而不是使用 System.Threading.Monitor的傳統 API。 如果您將 Lock
物件轉換成另一種類型,而且會產生以 Monitor
為基礎的程式代碼,編譯程式也會辨識。 您可以在 新鎖定物件的功能規格中了解更多信息。
這項功能可讓您透過變更物件 lock
的類型,以獲得新庫類型的優點。 不需要變更其他程序代碼。
新的逸出序列
您可以使用 \e
作為用於 ESCAPE
字元的 Unicode U+001B
的 字元字面值 轉義序列。 先前,您已使用 \u001b
或 \x1b
。 不建議使用 \x1b
,因為如果 1b
後面的下一個字元是有效的十六進位數位,這些字元就會成為逸出序列的一部分。
方法群組自然類型
這項功能可對涉及方法群組的多載解析進行小型優化。 方法群組 是方法,而且所有多載的名稱相同。 先前的行為是讓編譯程式建構方法群組的完整候選方法集合。 如果需要自然類型,則自然類型是從完整的候選方法集合決定。
新的行為是在每個範圍內篩選候選方法組,移除那些不適用的候選方法。 一般而言,移除的方法是具有錯誤參數個數的泛型方法,或未滿足的約束條件。 只有在找不到候選方法時,流程才會繼續進行到下一個外部範圍。 此程式更緊密地遵循多載解析的一般演算法。 如果在指定範圍中找到的所有候選方法都不符合,則方法群組沒有自然類型。
您可以在 提案規格中閱讀更動的詳細資料。
隱含索引存取
物件初始化表示式現在允許隱含的「from the end」索引運算子^
。 例如,您現在可以在物件初始化運算式中初始化陣列,如下列程式代碼所示:
public class TimerRemaining
{
public int[] buffer { get; set; } = new int[10];
}
var countdown = new TimerRemaining()
{
buffer =
{
[^1] = 0,
[^2] = 1,
[^3] = 2,
[^4] = 3,
[^5] = 4,
[^6] = 5,
[^7] = 6,
[^8] = 7,
[^9] = 8,
[^10] = 9
}
};
TimerRemaining
類別包含初始化為長度為 10 的 buffer
陣列。 上述範例使用「從結尾」索引運算子(^
),有效地建立了一個從 9 倒數到 0 的陣列,並指派數值給它。
在 C# 13 之前的版本中,無法在物件初始化表示式中使用 ^
運算子。 您需要從頭開始為元素建立索引。
迭代器和 async
方法中的 ref
和 unsafe
此功能和下列兩個功能可讓 ref struct
類型使用新的建構。 除非您撰寫自己的 ref struct
類型,否則您不會使用這些。 您可能更會看到當 System.Span<T> 和 System.ReadOnlySpan<T> 獲得更多功能時的間接好處。
在 C# 13 之前,反覆運算器方法(使用 yield return
的方法)和 async
方法無法宣告局部 ref
變數,也無法擁有 unsafe
內容。
在 C# 13 中,async
方法可以宣告 ref
局部變數或 ref struct
類型的局部變數。 不過,這些變數無法跨 await
界限存取。 兩者都無法跨 yield return
界限存取。
這項寬鬆的限制可讓編譯程式在更多地方安全地使用 ref
局部變數和 ref struct
類型。 您可以在這些方法中安全地使用 System.ReadOnlySpan<T> 這類類型。 編譯程式會告訴您是否違反安全規則。
同樣地,C# 13 允許反覆運算器方法中的 unsafe
內容。 不過,所有 yield return
和 yield break
語句都必須在安全的情境中。
allows ref struct
在 C# 13 之前,ref struct
類型無法宣告為泛型型別或方法的類型自變數。 現在,泛型型別宣告可以新增反條件約束,allows ref struct
。 這個反條件約束會宣告提供給該類型參數的類型自變數可以是 ref struct
類型。 編譯程式會對該類型參數的所有實例強制執行 ref 安全規則。
例如,您可以宣告泛型類型,例如下列程序代碼:
public class C<T> where T : allows ref struct
{
// Use T as a ref struct:
public void M(scoped T p)
{
// The parameter p must follow ref safety rules
}
}
這可讓 System.Span<T> 和 System.ReadOnlySpan<T> 等類型與適用的泛型演算法搭配使用。 您可以在 where
更新和程序設計指南一文中深入瞭解 泛型條件約束。
ref struct
介面
在 C# 13 之前,不允許 ref struct
類型實作介面。 從 C# 13 開始,這些功能可以實現。 您可以宣告 ref struct
類型實作介面。 不過,為了確保 ref 安全規則,ref struct
類型無法轉換成介面類型。 該轉換是拳擊轉換,而且可能會違反 ref safety。
ref struct
中的明確介面方法宣告只能透過類型參數來存取,其中該類型參數 allows ref struct
。 此外,ref struct
類型必須實作介面中宣告的所有方法,包括具有預設實作的方法。
進一步了解 ref struct
型別的相關更新,,以及加入了 allows ref struct
泛型約束條件。
更多次要成員
您可以在 C# 13 中宣告 partial
屬性和 partial
索引器。 部分屬性和索引器通常遵循與 partial
方法相同的規則:您會建立一個 宣告宣告,另一個 實作宣告。 兩個宣告的簽章必須相符。 其中一個限制是您無法使用自動屬性宣告,實作部分屬性。 未聲明主體的屬性被視為 的宣告。
public partial class C
{
// Declaring declaration
public partial string Name { get; set; }
}
public partial class C
{
// implementation declaration:
private string _name;
public partial string Name
{
get => _name;
set => _name = value;
}
}
您可以在文章中深入瞭解 部分成員。
重載解析優先順序
在 C# 13 中,編譯程式會辨識 OverloadResolutionPriorityAttribute 偏好一個多載而不是另一個多載。 函式庫作者可以使用這個屬性來確保新的、更好的多載被優先於現有的多載。 例如,您可以新增效能較強的新多載。 您不想中斷使用連結庫的現有程序代碼,但您希望使用者在重新編譯時更新為新版本。 您可以使用 多載解析優先順序,通知編譯程式應該首選某個多載。 優先選擇優先順序最高的多載。
這項功能是設計給程式庫作者,讓他們在新增多載時避免模棱兩可的情況。 連結庫作者應謹慎使用此屬性,以避免混淆。
field
關鍵詞
field
內容關鍵詞位於 C# 13 中作為預覽功能。 令牌 field
存取屬性存取子中由編譯器生成的支援欄位。 它可讓您撰寫存取子主體,而不需要在類型宣告中宣告明確的支援欄位。 您可以為以欄位支援的屬性,定義單個或雙個存取子的主體。
field
功能會以預覽功能的形式發行。 我們想要從您的體驗中學習。 在類型中包含名為 field
的欄位時,可能會發生潛在的重大變更或在讀取程式碼時造成混淆。 您可以使用 @field
或 this.field
來釐清 field
關鍵詞與標識符之間的混淆。
重要
field
關鍵詞是 C# 13 中的預覽功能。 您必須使用 .NET 9,並將您的 <LangVersion>
元素設定為項目檔中的 preview
,才能使用 field
內容關鍵詞。
您應該小心在具有名為 field
欄位的類別中使用 field
關鍵詞功能。 新的 field
關鍵詞會遮蔽屬性存取子範圍中名為 field
的欄位。 您可以變更 field
變數的名稱,或使用 @
令牌將 field
識別元參考為 @field
。 您可以閱讀 的 field
關鍵詞的規格說明來深入瞭解。
如果您嘗試此功能並有意見反應,請將其新增到 csharplang
存放庫中的 功能問題。