C# 12 中新增的八大功能你都知道吗?
内容提要
C# 12引入了8个新功能,包括主要构造函数、集合表达式、内联数组、lambda表达式中的可选参数、只读引用参数、任意类型的类型别名、实验性属性和拦截器。这些功能提升了C#编程的功能和性能。
延伸解读
主构造函数:简化初始化但需注意调用规则
C# 12 的主构造函数允许在类或结构声明中直接添加参数,这些参数在整个类主体中可用。但需注意:所有显式声明的构造函数都必须使用 this() 语法调用主构造函数,以确保参数被显式分配。此外,为 class 添加主构造函数会阻止编译器生成隐式无参构造函数,而 struct 的隐式无参构造函数会初始化所有字段,包括主构造函数参数。
集合表达式:统一语法与展开运算符
集合表达式提供了一种简洁的语法来创建数组、列表、Span 等常用集合,并支持使用展开运算符(..)将其他集合内联到新集合中。这减少了初始化集合时的样板代码,但需注意展开运算符的参数必须是集合类型,否则会导致编译错误。
内联数组:提升性能的底层工具
内联数组允许在结构类型中创建固定大小的数组,其性能特性类似于不安全固定大小缓冲区。运行时团队和库作者常用它来优化性能。使用时需通过 InlineArray 特性指定长度,并像普通数组一样通过索引访问元素。
实验性功能:谨慎使用拦截器和 Experimental 属性
拦截器允许在编译时替换方法调用,但属于实验性功能,可能在将来版本中发生破坏性变更或被移除,因此不建议用于生产环境。Experimental 属性用于标记实验性类型或方法,访问时会触发编译器警告,提醒开发者注意稳定性风险。
Q&A
C# 12 中新增了哪些主要功能?
C# 12 新增了八大功能:主构造函数、集合表达式、内联数组、Lambda 表达式中的可选参数、ref readonly 参数、任何类型的别名、Experimental 属性和拦截器。
C# 12 的主构造函数有什么作用?
主构造函数允许在类和结构中声明构造函数参数,这些参数在整个类主体范围内可用。所有显式声明的构造函数必须使用 this() 调用主构造函数。常见用途包括作为 base() 调用的参数、初始化成员字段或属性、引用实例成员中的构造函数参数。
C# 12 的集合表达式如何使用?
集合表达式提供简洁语法创建常用集合值,如数组、列表、Span 等。可以使用展开运算符(..)将其他集合内联到这些值中。例如:int[] array = [55, 99, 100, 33]; 或 int[] single = [.. item0, .. item1, .. item2];。
C# 12 的内联数组有什么优势?
内联数组允许在结构类型中创建固定大小的数组,从而提高应用程序性能。具有内联缓冲区的结构体应具有与不安全固定大小缓冲区类似的性能特性。声明方式如:[System.Runtime.CompilerServices.InlineArray(20)] public struct Buffer { private int _element0; }。
C# 12 中 Lambda 表达式支持可选参数吗?
是的,C# 12 允许为 Lambda 表达式的参数定义默认值,语法和规则与为方法或本地函数添加默认值相同。如果只有一个输入参数,括号可选;两个或更多参数用逗号分隔。注意:输入参数类型必须全部显式或全部隐式,否则会生成 CS0748 编译器错误。
C# 12 的 ref readonly 参数有什么作用?
ref readonly 修饰符表示方法希望参数是一个变量,而不是非变量表达式(如常量、方法返回值或属性)。如果参数不是变量,编译器会发出警告。
C# 12 中如何为任何类型创建别名?
可以使用 using alias 指令为任何类型创建别名,包括元组类型、数组类型、指针类型或其他不安全类型。例如:using PointTest = (int x, int y); 然后可以像使用普通类型一样使用 PointTest。
C# 12 的 Experimental 属性有什么用途?
Experimental 属性(System.Diagnostics.CodeAnalysis.ExperimentalAttribute)用于标记类型、方法或程序集,以指示实验性特征。访问使用该属性注释的方法或类型时,编译器会发出警告。用 Experimental 特性标记的程序集中包含的所有类型都是实验性的。
C# 12 的拦截器是什么?如何使用?
拦截器是一种方法,可以在编译时以声明方式将对可拦截方法的调用替换为对其自身的调用。通过声明所拦截调用的源位置进行替换。拦截器是实验性功能,在 C# 12 预览模式下提供,未来可能变更或删除,不建议用于生产。要使用拦截器,项目必须指定 <InterceptorsPreviewNamespaces> 属性,列出允许包含拦截器的命名空间。