可使用 return new(); 表达式返回由默认构造函数创建的实例。

类似的功能可改进条件表达式的目标类型解析。 进行此更改后,两个表达式无需从一个隐式转换到另一个,而是都可隐式转换为通用类型。 你可能不会注意到此更改。 你会注意到,某些以前需要强制转换或无法编译的条件表达式现在可以正常工作。

从 C# 9.0 开始,可将 static 修饰符添加到 Lambda 表达式或匿名方法。 静态 Lambda 表达式类似于 static 局部函数:静态 Lambda 或匿名函数无法捕获局部变量或实例状态。 static 修饰符可防止意外捕获其他变量。

协变返回类型为替代函数的返回类型提供了灵活性。 替代的虚函数可返回从基类方法中声明的返回类型派生的类型。 这对于记录和其他支持虚拟克隆或工厂方法的类型很有用。

此外,foreach 循环将识别并使用扩展方法 GetEnumerator,否则将满足 foreach 模式。 此更改意味着 foreach 与其他基于模式的构造(例如异步模式和基于模式的析构)一致。 实际上,此更改意味着可以为任何类型添加 foreach 支持。 在设计中,应将其限制为在枚举对象有意义时使用。

接下来,可使用弃元作为 Lambda 表达式的参数。 这样可免于为参数命名,并且编译器也可避免使用它。 可将 _ 用于任何参数。

最后,现在可将属性应用于本地函数。 例如,可将可为空的属性注释应用于本地函数。


C# 9.0 中的新增功能

支持代码生成器

最后两项功能支持 C# 代码生成器。 C# 代码生成器是可编写的组件,类似于 roslyn 分析器或代码修补程序。 区别在于,代码生成器会在编译过程中分析代码并编写新的源代码文件。 典型的代码生成器会在代码中搜索属性或其他约定。

代码生成器使用 Roslyn 分析 API 读取属性或其他代码元素。 通过该信息,它将新代码添加到编译中。 源生成器只能添加代码,不能修改编译中的任何现有代码。

为代码生成器添加的两项功能是分部方法语法和模块初始化表达式的扩展。 首先是对分部方法的更改。 在 C# 9.0 之前,分部方法为 private,但不能指定访问修饰符、不能返回 void,也不能具有 out 参数。 这些限制意味着,如果未提供任何方法实现,编译器会删除对分部方法的所有调用。 C# 9.0 消除了这些限制,但要求分部方法声明必须具有实现。 代码生成器可提供这种实现。 为了避免引入中断性变更,编译器会考虑没有访问修饰符的任何分部方法,以遵循旧规则。 如果分部方法包括 private 访问修饰符,则由新规则控制该分部方法。

代码生成器的第二项新功能是模块初始化表达式。 模块初始化表达式是附加了 ModuleInitializerAttribute 属性的方法。 程序集加载时,运行时将调用这些方法。 模块初始化表达式方法:

  • 必须是静态的

  • 必须没有参数

  • 必须返回 void

  • 不能是泛型方法

  • 不能包含在泛型类中

  • 必须能够从包含模块访问

最后一个要点实际上意味着该方法及其包含类必须是内部的或公共的。 方法不能为本地函数。


C# 9.0 中的新增功能

反馈