C# 11
新特性
更新: 2023-12-08 12:20:48 字数: 0 字 时长: 0 分钟
2022 年 11 月, C# 11 正式发布
原始字符串文本
原始字符串字面量是字符串字面量的一种新格式。 原始字符串字面量可以包含任意文本,包括空格、新行、嵌入引号和其他特殊字符,无需转义序列。 原始字符串字面量以至少三个双引号 (""") 字符开头。 它以相同数量的双引号字符结尾。 通常,原始字符串字面量在单个行上使用三个双引号来开始字符串,在另一行上用三个双引号来结束字符串。 左引号之后、右引号之前的换行符不包括在最终内容中:
string longMessage = """
This is a long message.
It has several lines.
Some are indented
more than others.
Some should start at the first column.
Some have "quoted text" in them.
""";
右双引号左侧的任何空格都将从字符串字面量中删除。 原始字符串字面量可以与字符串内插结合使用,以在输出文本中包含大括号。 多个 $ 字符表示有多少个连续的大括号开始和结束内插:
var location = $$"""
You are at {{{Longitude}}, {{Latitude}}}
""";
前面的示例指定了两个大括号开始和结束内插。 第三个重复的左大括号和右大括号包括在输出字符串中。
字符串插值允许换行
var str = $"hello, the leader is {group
.GetLeader()
.GetName()}.";
泛型属性
可以声明基类为 的泛型类。 此功能为需要 System.Type
参数的属性提供了更方便的语法。 以前需要创建一个属性,该属性将 Type
作为其构造函数参数:
// Before C# 11:
public class TypeAttribute : Attribute
{
public TypeAttribute(Type t) => ParamType = t;
public Type ParamType { get; }
}
并且为了应用该属性,需要使用 typeof 运算符:
[TypeAttribute(typeof(string))]
public string Method() => default;
使用此新功能,可以改为创建泛型属性:
// C# 11 feature:
public class GenericAttribute<T> : Attribute { }
然后指定类型参数以使用该属性:
[GenericAttribute<string>()]
public string Method() => default;
应用属性时,必须提供所有类型参数。 换句话说,泛型类型必须完全构造。 在上面的示例中,空括号 (( 和 )) 可以省略,因为 属性没有任何参数。
public class GenericType<T>
{
// Not allowed! generic attributes must be fully constructed types.
[GenericAttribute<T>()]
public string Method() => default;
}
类型参数必须满足与 typeof 运算符相同的限制。 不允许使用需要元数据注释的类型。 例如,不允许将以下类型用作类型参数:
dynamic
string?
(或任何可为 null 的引用类型)(int X, int Y)
(或使用 C# 元组语法的任何其他元组类型)。
这些类型不会直接在元数据中表示出来。 它们包括描述该类型的注释。 在所有情况下,都可以改为使用基础类型:
object
(对于dynamic
)。string
,而不是string?
。ValueTuple<int, int>
,而不是(int X, int Y)
。
必需的成员
可以将 required
修饰符添加到属性和字段,以强制构造函数和调用方初始化这些值。 可以将 System.Diagnostics.CodeAnalysis.SetsRequiredMembersAttribute
添加到构造函数,以通知编译器构造函数将初始化所有必需的成员。
有关所需成员的详细信息,请参阅属性文章的仅限初始化部分。
ref 字段和 ref scoped 变量
可以在 ref struct
中声明 ref
字段。 这支持没有特殊特性或隐藏的内部类型的 System.Span<T>
等类型。
可向任意 ref
声明添加 scoped
修饰符。 这限制了可将引用转义到的范围。