解决与语言功能和版本相关的警告
本文介绍以下编译器警告:
- 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:条件表达式在语言版本中无效,因为在类型之间找不到通用类型。
- CS8967:C# 不支持非逐字内插字符串内的换行符
- CS9014:错误:使用可能未分配的属性。升级到自动默认属性。
- CS9015:错误:使用可能未分配的字段。升级到自动默认字段。
- CS9016:警告:使用可能未分配的属性。升级到自动默认属性。
- CS9017:警告:使用可能未分配的字段。升级到自动默认字段。
- CS9064:目标运行时不支持 ref 字段。
- CS9103:模块中的定义具有无法识别的 RefSafetyRulesAttribute 版本,应为“11”。
- CS9171:目标运行时不支持内联数组类型。
- CS9194:自变量不可与
ref
关键字一起传递。要将ref
实参传递给in
形参,请升级到语言版本 12 或更高版本。 - CS9202:功能在 C# 12.0 中不可用。请使用较新的语言版本
- CS9211:“Experimental”属性的 diagnosticId 自变量必须是有效的标识符。
- CS9240:目标运行时不支持 by-ref-like 泛型。
此外,以下错误和警告与最新版本中的结构初始化变更相关:
- CS0171、CS8881:在控件返回调用方之前,自动实现的属性“name”的支持字段必须完全赋值。
- CS0188、CS8885:在给“this”对象的所有字段赋值之前,无法使用该对象
- CS0843、CS8880:在控件返回调用方之前,自动实现的属性“name”的支持字段必须完全赋值
- CS8305:功能仅用于评估目的,在将来的更新中可能会被更改或删除。
- CS9204:类型仅用于评估目的,在将来的更新中可能会被更改或删除。取消此诊断以继续。
导致上述所有错误和警告的原因是安装的编译器支持的 C# 版本比项目选择的版本更高。 C# 编译器可以符合以前的任何版本。 可以针对早期版本的 C# 验证语法,或者因为项目必须支持更低版本的库或运行时。
有两种可能的原因和三种方法来解决这些错误和警告。
更新目标框架
编译器根据以下规则确定默认值:
目标 | 版本 | C# 语言版本的默认值 |
---|---|---|
.NET | 9.x | C# 13 |
.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 |
编译器接受最新发布的编译器主要版本中的语法。 |
13.0 |
编译器只接受 C# 13 或更低版本中所含的语法。 |
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;
}
}