控制代码生成的 C# 编译器选项

下面的选项控制编译器生成的代码。 新的 MSBuild 语法以粗体显示。 旧的 csc.exe 语法以 code style 显示。

  • DebugType / -debug:发出(或不发出)调试信息。
  • Optimize / -optimize:启用优化。
  • Deterministic / -deterministic:从相同的输入源生成每字节对等的输出。
  • ProduceOnlyReferenceAssembly / -refonly:生成引用程序集作为主输出,而非生成完整程序集。

DebugType

DebugType 选项将使编译器生成调试信息,并将此信息放置在一个或多个输出文件中。 默认情况下会添加调试信息。

<DebugType>pdbonly</DebugType>

自 C# 6.0 起,对于所有编译器版本而言,pdbonly 与 full 之间没有任何区别。 请选择 pdbonly。 若要更改 .pdb 文件的位置,请参阅 PdbFile

以下为有效值:

Value 含义
full 使用当前平台的默认格式向 .pdb 文件发出调试信息:
Windows:Windows pdb 文件。
Linux/macOS:可移植 PDB 文件。
pdbonly full 相同。 有关详细信息,请参阅下面的注释。
portable 使用跨平台可移植 PDB 格式向 .pdb 文件发出调试信息。
embedded 使用可移植 PDB 格式向 .dll/.exe 自身(未生成 .pdb 文件)发出调试信息。

重要

以下信息仅适用于 C# 6.0 以前的编译器。 此元素的值可以是 fullpdbonly。 full 参数(在不指定 pdbonly 时生效)允许将调试器附加到正在运行的程序。 指定 pdbonly 后,可以在调试器中启动程序时进行源代码调试,但仅在正在运行的程序附加到调试器时才显示汇编程序。 使用此选项创建调试版本。 如果使用 Full,请注意,对经过优化的 JIT 代码的速度和大小会存在一定影响,使用 full 时对代码质量的影响较小 。 建议使用 pdbonly 或不使用 PDB 生成发布代码。 pdbonly 和 full 之间的一个区别在于,使用 full,编译器将发出 DebuggableAttribute,用于告知 JIT 编译器有可用调试信息 。 因此,在使用 full 时,如果代码包含设置为 false 的 DebuggableAttribute,将出现错误。 有关如何配置应用程序的调试性能的详细信息,请参阅令映像更易于调试

优化

Optimize 选项启用或禁用编译器执行的优化,使输出文件更小、更快、更有效。 默认情况下,为发布生成配置启用 Optimize 选项。 默认情况下,为调试和任何其他生成配置禁用此选项。

<Optimize>true</Optimize>

在 Visual Studio 中,可以从项目的“生成”属性页中设置 Optimize 选项。

Optimize 还指示公共语言运行时在运行时优化代码。 默认情况下,禁用优化。 指定 Optimize+ 可启用优化。 生成程序集使用的模块时,请使用与程序集所使用的相同 Optimize 设置。 可以将 Optimize 和 Debug 选项组合使用。

具有确定性

如果输入相同,则会导致编译器生成的程序集其逐字节输出在整个编译期间中相同。

<Deterministic>true</Deterministic>

默认情况下,来自一组给定输入的编译器输出是唯一的,因为编译器添加从随机数生成的时间戳和 MVID(Module.ModuleVersionId。基本上,它是一个 GUID,用于唯一标识模块和版本)。 使用 <Deterministic> 选项生成确定性的程序集,只要输入保持不变,该程序集的二进制内容在整个编译中都是相同的 。 在此类生成中,时间戳和 MVID 字段会被替换为从所有编译输入的哈希派生的值。 编译器会考虑影响确定性的以下输入:

  • 命令行参数序列。
  • 编译器 .rsp 响应文件的内容。
  • 所用编译器的精确版本及其引用的程序集。
  • 当前目录路径。
  • 直接或间接地显式传递到编译器的所有文件的二进制内容,包括:
    • 源文件
    • 引用的程序集
    • 引用的模块
    • 资源
    • 强名称密钥文件
    • @ 响应文件
    • 分析器
    • 规则集
    • 分析器可能使用的其他文件
  • 当前区域性(针对生成诊断和异常消息的语言)。
  • 在未指定编码情况下使用的默认编码(或当前代码页)。
  • 编译器搜索路径(例如,由-lib-recurse 指定)上文件是否存在及其内容。
  • 运行编译器的公共语言运行时 (CLR) 平台。
  • %LIBPATH% 的值,该值会影响分析器的依赖项加载。

可使用确定性编译来确定是否从可信源编译二进制内容。 当源公开可用时,确定性输出会很有用。 它还可以确定生成步骤是否依赖于生成过程中使用的二进制文件的更改。

ProduceOnlyReferenceAssembly

ProduceOnlyReferenceAssembly 选项表示应输出引用程序集(而不是实现程序集)作为主输出。 ProduceOnlyReferenceAssembly 参数以无提示方式禁用输出 PDB,因为无法执行引用程序集。

<ProduceOnlyReferenceAssembly>true</ProduceOnlyReferenceAssembly>

引用程序集是一种特殊类型的程序集。 引用程序集只包含表示库的公共 API 外围应用所需的最少元数据量。 它们包括在生成工具中引用程序集时所需的所有成员的声明,但不包括所有成员实现以及对其 API 协定没有明显影响的私有成员的声明。 有关详细信息,请参阅引用程序集

ProduceOnlyReferenceAssembly 和 ProduceReferenceAssembly 选项是互斥的。