用于语言功能规则的 C# 编译器选项

以下选项控制编译器如何解释语言功能。 新的 MSBuild 语法以粗体显示。 旧的 csc.exe 语法以 code style 显示。

  • CheckForOverflowUnderflow / -checked:生成溢出检查。
  • AllowUnsafeBlocks / -unsafe:允许“不安全”代码。
  • DefineConstants / -define:定义条件编译符号。
  • LangVersion / -langversion:指定语言版本,如 default(最新主版本)或 latest(最新版本,包括次要版本)。
  • Nullable / -nullable:启用可为空上下文或可为空警告。

CheckForOverflowUnderflow

CheckForOverflowUnderflow选项控制在整数算术溢出的情况下定义程序行为的默认溢出检查上下文。

<CheckForOverflowUnderflow>true</CheckForOverflowUnderflow>

CheckForOverflowUnderflow 为 true 时,默认上下文为已检查上下文,并且启用了溢出检查;否则,默认上下文为未检查的上下文。 此选项的默认值为 false,即禁用溢出检查。

还可以使用 checkedunchecked 语句显式控制代码部分的溢出检查上下文。

有关溢出检查上下文如何影响操作以及哪些操作受到影响的信息,请参阅关于 checkedunchecked 语句的文章

AllowUnsafeBlocks

AllowUnsafeBlocks 编译器选项允许使用 unsafe 关键字的代码进行编译。 此选项的默认值为false,表示不允许不安全代码。

<AllowUnsafeBlocks>true</AllowUnsafeBlocks>

有关不安全代码的详细信息,请参阅不安全代码和指针

DefineConstants

DefineConstants 选项将定义程序中所有源代码文件的符号。

<DefineConstants>name;name2</DefineConstants>

此选项指定要定义的一个或多个符号的名称。 DefineConstants 选项具有与 #define 预处理器指令相同的效果,只不过编译器选项对项目中的所有文件都有效。 符号在源文件中保持已定义状态,直到源文件中的 #undef 指令删除该定义。 当你使用 -define 选项时,一个文件中的 #undef 指令不影响项目中的其他源代码文件。 可以将由此选项创建的符号同 #if#else#elif#endif 一起使用,对源文件进行条件编译。 C# 编译器本身不定义源代码中使用的符号或宏;所有符号定义必须都是用户定义的。

注意

同 C++ 等语言一样,C# #define 指令不允许为符号赋值。 例如,#define 不能用于创建宏或定义常数。 如果需要定义一个常数,请使用 enum 变量。 若要创建 C++ 风格的宏,请考虑泛型等替代项。 由于宏非常容易出错,所以 C# 不允许使用宏,但提供了更安全的替代项。

LangVersion

C# 编译器的默认语言版本依赖于应用程序的目标框架以及所安装的 SDK 或 Visual Studio 的版本。 这些规则是在 C# 语言版本控制中定义的。

LangVersion 选项使编译器仅接受指定 C# 语言规范中包含的语法,例如:

<LangVersion>9.0</LangVersion>

以下为有效值:

Value 含义
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) 中所含的语法。

重要

通常不建议使用latest值。 借助 latest,编译器可以启用最新功能,即使这些功能依赖于未包含在配置的目标框架中的更新。

注意事项

  • 若要确保项目使用为目标框架推荐的默认编译器版本,请不要使用 LangVersion 选项。 可更新目标框架以访问更新的语言功能。

  • 使用 default 值指定 LangVersion 与省略 LangVersion 选项不同。 指定 default 会使用编译器支持的语言的最新版本,而不考虑目标框架。 例如,如果未指定 LangVersion,则通过 Visual Studio 版本 17.6 生成面向 .NET 6 的项目将使用 C# 10,但如果 LangVersion 设置为 default,则使用 C# 11。

  • C# 应用程序引用的元数据不受 LangVersion 编译器选项约束。

  • 每个版本的 C# 编译器都包含语言规范的扩展,因此 LangVersion 不提供早期版本编译器的同等功能。

  • 虽然 C# 版本更新通常与主要的 .NET 版本一致,但新的语法和功能不一定会绑定到该特定的 Framework 版本。 每项具体功能都有自己的最小 .NET API 或公共语言运行时要求,这些要求通过包括 NuGet 包或其他库允许功能在下层框架上运行。

  • 无论使用哪一项 LangVersion 设置,请使用当前版本的公共语言运行时来创建 .exe 或 .dll。 友元程序集和 ModuleAssemblyName 是一个例外,它们在 -langversion:ISO-1 下工作。

若要了解指定 C# 语言版本的其他方式,请参阅 C# 语言版本控制

有关如何以编程方式设置此编译器选项的信息,请参阅 LanguageVersion

C# 语言规范

Version 链接 说明
C# 8.0 和更高版本 下载 PDF C# 语言规范版本 7:.NET Foundation
C# 7.3 下载 PDF 标准 ECMA-334 第 7 版
C# 6.0 下载 PDF 标准 ECMA-334 第 6 版
C# 5.0 下载 PDF 标准 ECMA-334 第 5 版
C# 3.0 下载 DOC C# 语言规范版本 3.0:Microsoft Corporation
C# 2.0 下载 PDF 标准 ECMA-334 第 4 版
C# 1.2 下载 DOC 标准 ECMA-334 第 2 版
C# 1.0 下载 DOC 标准 ECMA-334 第 1 版

支持所有语言功能所需的最低 SDK 版本

下表列出了支持相应语言版本的 C# 编译器的 SDK 的最低版本:

C# 版本 最低 SDK 版本
C# 12 Microsoft Visual Studio/生成工具 2022,版本 17.8 或 .NET 8 SDK
C# 11 Microsoft Visual Studio/生成工具 2022,版本 17.4 或 .NET 7 SDK
C# 10 Microsoft Visual Studio/生成工具 2022 或 .NET 6 SDK
C# 9.0 Microsoft Visual Studio/生成工具 2019 版本 16.8 或 .NET 5 SDK
C# 8.0 Microsoft Visual Studio/生成工具 2019,版本 16.3 或 .NET Core 3.0 SDK
C# 7.3 Microsoft Visual Studio/生成工具 2017,版本 15.7
C# 7.2 Microsoft Visual Studio/生成工具 2017,版本 15.5
C# 7.1 Microsoft Visual Studio/生成工具 2017,版本 15.3
C# 7.0 Microsoft Visual Studio/生成工具 2017
C# 6 Microsoft Visual Studio/生成工具 2015
C# 5 Microsoft Visual Studio/生成工具 2012 或捆绑的 .NET Framework 4.5 编译器
C# 4 Microsoft Visual Studio/生成工具 2010 或捆绑的 .NET Framework 4.0 编译器
C# 3 Microsoft Visual Studio/生成工具 2008 或捆绑的 .NET Framework 3.5 编译器
C# 2 Microsoft Visual Studio/生成工具 2005 或捆绑的 .Net Framework 2.0 编译器
C# 1.0/1.2 Microsoft Visual Studio/生成工具 .NET 2002 或捆绑的 .NET Framework 1.0 编译器

Nullable

使用 Nullable 选项可指定可为空上下文。 可以使用 <Nullable> 标记在项目的配置中设置它:

<Nullable>enable</Nullable>

参数必须为以下项之一:enabledisablewarningsannotationsenable 参数启用可为空上下文。 指定 disable 将禁用可为空上下文。 如果指定warnings参数,会启用可为空警告上下文。 如果指定annotations参数,会启用可为空注释上下文。 有关可为空上下文的文章中对这些值进行了描述和说明。 可以在有关可为空迁移策略的文章中详细了解在现有代码库中启用可为空引用类型所涉及的任务。

注意

未设置任何值时,将应用默认值 disable,但默认提供 .NET 6 模板,其 Nullable 值设置为 enable

流分析用于在可执行代码中推断变量的为空性。 推断出的变量的为空性与变量声明的为空性无关。 即使有条件地省略方法调用,也会对其进行分析。 例如,发布模式下的 Debug.Assert

采用以下特性进行注释的方法调用也将影响流分析:

重要

全局可为空上下文不适用于生成的代码文件。 无论此设置如何,都会针对标记为“已生成”的任何源文件禁用可为空上下文。 可采用四种方法将文件标记为“已生成”:

  1. 在 .editorconfig 中,在应用于该文件的部分中指定 generated_code = true
  2. <auto-generated><auto-generated/> 放在文件顶部的注释中。 它可以位于该注释中的任意行上,但注释块必须是该文件中的第一个元素。
  3. 文件名以 TemporaryGeneratedFile_ 开头
  4. 文件名用以 .designer.cs、.generated.cs、.g.cs 或 .g.i.cs 结尾 。

生成器可以选择使用 #nullable 预处理器指令。