本文內容
- 泛型屬性
- 泛型數學支持
- 數值 IntPtr 和 UIntPtr
- 字符串內插中的換行符
顯示另外 11 個
C# 11 中增加了以下功能:
- 原始字符串字面量
- 泛型數學支持
- 泛型屬性
- UTF-8 字符串字面量
- 字符串內插表達式中的換行符
- 列表模式
- 文件本地類型
- 必需的成員
- 自動默認結構
- 常量?string?上的模式匹配?Span<char>
- 擴展的?nameof?范圍
- 數值 IntPtr
- ref?字段和?scoped ref
- 改進了方法組向委托的轉換
- 警告波 7
.NET 7 支持 C# 11。 有關詳細信息,請參閱?C# 語言版本控制。
可以通過?.NET 下載頁下載最新 .NET 7 SDK。 還可以下載?Visual Studio 2022,其中包括 .NET 7 SDK。
?備注
我們有興趣了解你對這些功能的反饋。 如果發現這些新功能存在問題,請在?dotnet/roslyn?存儲庫中創建新問題。
泛型屬性
可以聲明基類為?的泛型類。 此功能為需要?System.Type?參數的屬性提供了更方便的語法。 以前需要創建一個屬性,該屬性將?Type
?作為其構造函數參數:
C#復制
// Before C# 11:
public class TypeAttribute : Attribute
{public TypeAttribute(Type t) => ParamType = t;public Type ParamType { get; }
}
并且為了應用該屬性,需要使用?typeof?運算符:
C#復制
[TypeAttribute(typeof(string))]
public string Method() => default;
使用此新功能,可以改為創建泛型屬性:
C#復制
// C# 11 feature:
public class GenericAttribute<T> : Attribute { }
然后指定類型參數以使用該屬性:
C#復制
[GenericAttribute<string>()]
public string Method() => default;
應用屬性時,必須提供所有類型參數。 換句話說,泛型類型必須完全構造。 在上面的示例中,可以省略空括號 ((
?和?)
),因為特性沒有任何參數。
C#復制
public class GenericType<T>
{[GenericAttribute<T>()] // Not allowed! generic attributes must be fully constructed types.public string Method() => default;
}
類型參數必須滿足與?typeof?運算符相同的限制。 不允許使用需要元數據注釋的類型。 例如,不允許將以下類型用作類型參數:
dynamic
string?
(或任何可為 null 的引用類型)(int X, int Y)
(或使用 C# 元組語法的任何其他元組類型)。
這些類型不會直接在元數據中表示出來。 它們包括描述該類型的注釋。 在所有情況下,都可以改為使用基礎類型:
object
(對于?dynamic
)。string
,而不是?string?
。ValueTuple<int, int>
,而不是?(int X, int Y)
。
泛型數學支持
有幾個語言功能支持泛型數學支持:
static virtual
?接口中的成員- 已檢查的用戶定義的運算符
- 寬松移位運算符
- 無符號右移運算符
可以在接口中添加?static abstract
?或?static virtual
?成員,以定義包含可重載運算符、其他靜態成員和靜態屬性的接口。 此功能的主要場景是在泛型類型中使用數學運算符。 例如,可以在實現?operator +
?的類型中實現?System.IAdditionOperators<TSelf, TOther, TResult>
?接口。 其他接口定義其他數學運算或明確定義的值。 可以在有關接口的文章中了解新語法。 包含?static virtual
?方法的接口通常是泛型接口。 此外,大部分將聲明一個約束,即類型參數實現聲明接口。
可以在探索靜態抽象接口成員教程或?.NET 6 中的預覽功能 - 泛型數學博客文章中了解詳細信息并親自嘗試該功能。
泛型數學對語言創建了其他要求。
- 無符號右移運算符:在 C# 11 之前,若要強制無符號右移,需要將任何帶符號整數類型強制轉換為無符號類型,執行移動,然后將結果強制轉換回帶符號類型。 從 C# 11 開始,可以使用?
>>>
無符號移動運算符。 - 寬松的移動運算符要求:C# 11 刪除了第二個操作數必須是?
int
?或隱式轉換為?int
?的要求。 此更改允許在這些位置使用實現泛型數學接口的類型。 - 已檢查和未檢查的用戶定義運算符:開發人員現在可以定義?
checked
?和?unchecked
?算術運算符。 編譯器根據當前上下文生成對正確變體的調用。 有關?checked
?運算符的詳細信息,可以閱讀有關算術運算符的文章。
數值?IntPtr
?和?UIntPtr
現在?nint
?和?nuint
?類型的別名分別為?System.IntPtr?和?System.UIntPtr。
字符串內插中的換行符
字符串內插的?{
?和?}
?字符內的文本現在可以跨多個行。?{
?和?}
?標記之間的文本分析為 C#。 允許任何合法 C#(包括換行符)。 使用此功能可以更輕松地讀取使用較長 C# 表達式的字符串內插,例如模式匹配?switch
?表達式或 LINQ 查詢。
可以在語言參考的字符串內插文章中了解有關換行符功能的詳細信息。
列表模式
列表模式擴展了模式匹配,以匹配列表或數組中的元素序列。 例如,當?sequence
?為數組或三個整數(1、2 和 3)的列表時,sequence is [1, 2, 3]
?為?true
。 可以使用任何模式(包括常量、類型、屬性和關系模式)來匹配元素。 棄元模式 (_
) 匹配任何單個元素,新的范圍模式 (..
) 匹配零個或多個元素的任何序列。
可以在語言參考的模式匹配文章中了解有關列表模式的更多詳細信息。
改進了方法組向委托的轉換
方法組轉換上的 C# 標準現在包含以下項:
- 允許轉換(但不是必需的)以使用已包含這些引用的現有委托實例。
以前版本的標準禁止了編譯器重用為方法組轉換而創建的委托對象。 C# 11 編譯器緩存從方法組轉換創建的委托對象,并重用該單個委托對象。 此功能最初在 Visual Studio 2022 版本 17.2 中作為預覽功能提供,在 .NET 7 預覽版 2 中首次提供。
原始字符串文本
原始字符串字面量是字符串字面量的一種新格式。 原始字符串字面量可以包含任意文本,包括空格、新行、嵌入引號和其他特殊字符,無需轉義序列。 原始字符串字面量以至少三個雙引號 (""") 字符開頭。 它以相同數量的雙引號字符結尾。 通常,原始字符串字面量在單個行上使用三個雙引號來開始字符串,在另一行上用三個雙引號來結束字符串。 左引號之后、右引號之前的換行符不包括在最終內容中:
C#復制
string longMessage = """This is a long message.It has several lines.Some are indentedmore than others.Some should start at the first column.Some have "quoted text" in them.""";
右雙引號左側的任何空格都將從字符串字面量中刪除。 原始字符串字面量可以與字符串內插結合使用,以在輸出文本中包含大括號。 多個?$
?字符表示有多少個連續的大括號開始和結束內插:
C#復制
var location = $$"""You are at {{{Longitude}}, {{Latitude}}}""";
前面的示例指定了兩個大括號開始和結束內插。 第三個重復的左大括號和右大括號包括在輸出字符串中。
可以在編程指南中關于字符串的文章中,以及關于字符串字面量和內插字符串的語言參考文章中詳細了解原始字符串字面量。
自動默認結構
C# 11 編譯器可以確保在執行構造函數的過程中,將?struct
?類型的所有字段初始化為其默認值。 此更改意味著,任何未由構造函數初始化的字段或自動屬性都由編譯器自動初始化。 現在,構造函數未明確分配所有字段的結構可以進行編譯,并且未顯式初始化的任何字段都設置為其默認值。 有關此更改如何影響結構初始化的詳細信息,請閱讀有關結構的文章。
常量?string
?上的模式匹配?Span<char>
?或?ReadOnlySpan<char>
你已經能夠在幾個版本中使用模式匹配來測試?string
?是否有某個特定的常量值。 現在,可以將同一模式匹配邏輯用于?Span<char>
?或?ReadOnlySpan<char>
?的變量。
擴展的 nameof 范圍
在該方法的屬性聲明中的?nameof
?表達式中使用時,類型參數名稱和參數名稱現在處于范圍內。 此功能意味著可以使用?nameof
?運算符在方法或參數聲明的屬性中指定方法參數的名稱。 此功能最常用于為可為空分析添加屬性。
UTF-8 字符串字面量
可以對字符串字面量指定?u8
?后綴來指定 UTF-8 字符編碼。 如果應用程序需要 UTF-8 字符串,則對于 HTTP 字符串常量或類似的文本協議來說,可以使用此功能來更輕松地創建 UTF-8 字符串。
有關 UTF-8 字符串字面量的詳細信息,請參閱關于內置引用類型的文章的字符串字面量部分。
必需的成員
可以將?required?修飾符添加到屬性和字段,以強制構造函數和調用方初始化這些值。 可以將?System.Diagnostics.CodeAnalysis.SetsRequiredMembersAttribute?添加到構造函數,以通知編譯器構造函數將初始化所有必需的成員。
有關所需成員的詳細信息,請參閱屬性文章的僅限初始化部分。
ref
?字段和?ref scoped
?變量
可以在?ref struct?中聲明?ref
?字段。 這支持沒有特殊特性或隱藏的內部類型的?System.Span<T>?等類型。
可向任意?ref
?聲明添加?scoped?修飾符。 這限制了可將引用轉義到的范圍。
文件本地類型
從 C# 11 開始,可以使用?file
?訪問修飾符創建其可見性范圍限定為其聲明時所在的源文件的類型。 此功能可幫助源生成器創建者避免命名沖突。 可以在語言參考中有關文件范圍類型的文章中詳細了解此功能。