解决与语言功能和版本相关的警告

本文介绍以下编译器警告:

  • CS8022、CS8023、CS8024、CS8025、CS8026、CS8059、CS8107、CS8302、CS8320、CS8370、CS8400、CS8773、CS8936、CS9058功能不可用。使用较新的语言版本。
  • CS8058功能是试验性的。
  • CS8192提供的语言版本不受支持或无效
  • CS8303指定的语言版本不能包含前导零
  • CS8304编译器版本低于语言版本
  • CS1738在所有固定参数均已指定后,必须显示命名参数规范。
  • CS8306已推断元组元素名称。
  • CS8314类型的模式无法处理类型的表达式
  • CS8371语言版本中不支持自动属性的字段针对特性
  • CS8401若要对内插逐字字符串使用 @$ 而不是 $@,请使用较新的语言版本。
  • CS8511类型的模式无法处理类型的表达式。
  • CS8627可为 null 的类型参数必须已知为值类型或不可为 null 引用类型
  • CS8630无效的可为 null 的选项。使用较新的语言版本
  • CS8652修饰符对此项目无效。
  • CS8704类型不实现接口成员。它无法隐式实现非公共成员。
  • CS8706类型无法实现接口成员,因为此版本中不提供某个功能。
  • CS8904方差无效:类型参数必须有效。
  • CS8912不支持从具有密封的“Object.ToString”的记录继承。
  • CS8919:无法在类型中实现指定的接口成员,因为目标运行时不支持接口中的静态抽象成员
  • CS8929:方法无法在类型中实现接口成员,因为目标运行时不支持接口中的静态抽象成员。
  • CS8957条件表达式在语言版本中无效,因为在类型之间找不到通用类型。
  • CS8967C# 不支持非逐字内插字符串内的换行符
  • CS9014错误:使用可能未分配的属性。升级到自动默认属性。
  • CS9015错误:使用可能未分配的字段。升级到自动默认字段。
  • CS9016警告:使用可能未分配的属性。升级到自动默认属性。
  • CS9017警告:使用可能未分配的字段。升级到自动默认字段。
  • CS9064目标运行时不支持 ref 字段。
  • CS9103模块中的定义具有无法识别的 RefSafetyRulesAttribute 版本,应为“11”。
  • CS9171目标运行时不支持内联数组类型。
  • CS9194自变量不可与 ref 关键字一起传递。要将 ref 实参传递给 in 形参,请升级到语言版本 12 或更高版本。
  • CS9202功能在 C# 12.0 中不可用。请使用较新的语言版本
  • CS9211“Experimental”属性的 diagnosticId 自变量必须是有效的标识符。

此外,以下错误和警告与最新版本中的结构初始化变更相关:

导致上述所有错误和警告的原因是安装的编译器支持的 C# 版本比项目选择的版本更高。 C# 编译器可以符合以前的任何版本。 可以针对早期版本的 C# 验证语法,或者因为项目必须支持更低版本的库或运行时。

有两种可能的原因和三种方法来解决这些错误和警告。

更新目标框架

编译器根据以下规则确定默认值:

目标 版本 C# 语言版本的默认值
.NET 8.x C# 12
.NET 7.x C# 11
.NET 6.x C# 10
.NET 5.x C# 9.0
.NET Core 3.x C# 8.0
.NET Core 2.x C# 7.3
.NET Standard 2.1 C# 8.0
.NET Standard 2.0 C# 7.3
.NET Standard 1.x C# 7.3
.NET Framework 全部 C# 7.3

如果所选框架与所需的语言版本不匹配,可以升级目标框架。

选择匹配的语言版本

你可能在项目文件中选择了更低版本的目标框架。 如果从项目文件中删除 LangVersion 元素,编译器将使用上一部分中列出的默认值。 下表显示当前所有 C# 语言版本。 还可以指定特定语言版本来启用新功能。

含义
preview 编译器接受最新预览版中的所有有效语言语法。
latest 编译器接受最新发布的编译器版本(包括次要版本)中的语法。
latestMajor
default
编译器接受最新发布的编译器主要版本中的语法。
12.0 编译器只接受 C# 12 或更低版本中所含的语法。
11.0 编译器只接受 C# 11 或更低版本中包含的语法。
10.0 编译器只接受 C# 10 或更低版本中所含的语法。
9.0 编译器只接受 C# 9 或更低版本中所含的语法。
8.0 编译器只接受 C# 8.0 或更低版本中所含的语法。
7.3 编译器只接受 C# 7.3 或更低版本中所含的语法。
7.2 编译器只接受 C# 7.2 或更低版本中所含的语法。
7.1 编译器只接受 C# 7.1 或更低版本中所含的语法。
7 编译器只接受 C# 7.0 或更低版本中所含的语法。
6 编译器只接受 C# 6.0 或更低版本中所含的语法。
5 编译器只接受 C# 5.0 或更低版本中所含的语法。
4 编译器只接受 C# 4.0 或更低版本中所含的语法。
3 编译器只接受 C# 3.0 或更低版本中所含的语法。
ISO-2
2
编译器只接受 ISO/IEC 23270:2006 C# (2.0) 中所含的语法。
ISO-1
1
编译器只接受 ISO/IEC 23270:2003 C# (1.0/1.2) 中所含的语法。

可以在配置语言版本一文中的“语言参考”部分详细了解每个框架版本支持的语言版本。

避免使用更新的功能

如果必须支持更低版本的库或运行时,则可能需要避免使用新功能。

启用实验性功能

可以禁用实验性功能的诊断以使用实验性功能。

警告

实验性功能可能会随时更改。 API 可能会更改,或者可能会在未来的更新中被删除。 包括实验性功能是库作者获取有关未来开发的想法和概念反馈的一种方式。 使用标记为实验性的任何功能时,请格外小心。

还可以使用 System.Diagnostics.CodeAnalysis.ExperimentalAttribute 声明自己的试验性功能。 如果用于试验性功能的标识符不是有效的标识符,则编译器将发出 CS9211

结构初始化的中断性变更

所有这些错误和警告都有助于确保 struct 类型在访问其字段之前已正确初始化。 在早期版本的 C# 中,必须在任何构造函数中显式赋值结构中的所有字段。 无参数构造函数将所有字段初始化为其默认值。 在更高版本中,所有构造函数将初始化所有字段。 显式设置字段,在字段初始值设定项中设置,或设置为其默认值。

  • CS0171、CS8881:在控件返回调用方之前,自动实现的属性“name”的支持字段必须完全赋值。
  • CS0188、CS8885:在给“this”对象的所有字段赋值之前,无法使用该对象
  • CS0843、CS8880:在控件返回调用方之前,自动实现的属性“name”的支持字段必须完全赋值

可以通过将语言版本升级到 C# 11 来解决此错误,每个 struct 构造函数都会初始化所有字段。 如果无法执行此操作,则必须显式调用默认构造函数,如以下示例所示:

struct S
{
    public int AIProp { get; set; }
    public S(int i){} //CS0843
    // Try the following lines instead.
    // public S(int i) : this()
    // {
    //     AIProp = i;
    // }
}

class Test
{
    static int Main()
    {
        return 1;
    }
}