You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C#增量源生成器中访问编译时配置与常量?

问题

我采用增量生成器方式编写C#源生成器,希望允许开发者通过两种方式控制额外代码(如注释、调试输出、严格校验等)的生成:一是在使用该生成器的项目.csproj中添加DefineConstants;二是通过dotnet build命令行的-p参数。我查看了IncrementalGeneratorInitializationContext、SourceProductionContext、Compilation等类型,未找到相关访问方式。目前的替代方案是使用自定义属性,但需要开发者手动多次添加,请问是否有办法在增量生成器工作流中访问这两类编译时设置?

解决方案

当然可以访问这两类编译时设置,核心是利用Compilation对象的编译选项获取常量,以及通过AnalyzerConfigOptionsProvider读取项目级MSBuild属性(包括命令行传入的-p参数)。

1. 访问DefineConstants编译常量

在增量生成器的处理逻辑中,你可以通过Compilation.Options拿到CSharpCompilationOptions,进而直接获取DefineConstants集合:

// 在增量生成器的节点处理逻辑中
var hasDebugOutput = compilation.Options.DefineConstants.Contains("GENERATOR_DEBUG_OUTPUT");
var enableStrictValidation = compilation.Options.DefineConstants.Contains("GENERATOR_STRICT_VALIDATION");

开发者只需通过两种方式传入常量:

  • 在项目.csproj中配置:
<PropertyGroup>
  <DefineConstants>$(DefineConstants);GENERATOR_DEBUG_OUTPUT;GENERATOR_STRICT_VALIDATION</DefineConstants>
</PropertyGroup>
  • 或者通过命令行传入:
dotnet build -p:DefineConstants="GENERATOR_DEBUG_OUTPUT;GENERATOR_STRICT_VALIDATION"

生成器读取到这些常量后,即可根据判断结果控制代码生成逻辑。

2. 访问MSBuild属性(含命令行-p参数)

增量生成器可以通过IncrementalGeneratorInitializationContext注册AnalyzerConfigOptionsProvider作为数据源,以此获取项目级的MSBuild属性:

步骤1:注册数据源并读取配置

public void Initialize(IncrementalGeneratorInitializationContext context)
{
    // 注册全局配置作为数据源
    var globalConfig = context.AnalyzerConfigOptionsProvider.Select((provider, _) => provider.GlobalOptions);
    
    // 将配置与你需要处理的语法节点关联
    var combinedData = context.SyntaxProvider
        .CreateSyntaxProvider(/* 你的语法筛选逻辑 */)
        .Combine(globalConfig);
    
    // 注册代码生成逻辑
    context.RegisterSourceOutput(combinedData, (spc, data) =>
    {
        var (targetNode, options) = data;
        // 读取项目中配置的自定义属性
        if (options.TryGetValue("build_property.Generator_EnableComments", out var enableCommentsStr) && 
            bool.TryParse(enableCommentsStr, out var enableComments))
        {
            // 根据配置生成带注释的代码
        }
        
        // 读取命令行传入的-p参数(比如dotnet build -p:Generator_DebugMode=true)
        if (options.TryGetValue("build_property.Generator_DebugMode", out var debugModeStr) && 
            bool.TryParse(debugModeStr, out var debugMode))
        {
            // 生成调试输出相关代码
        }
    });
}

步骤2:开发者配置方式

  • 在项目.csproj中添加:
<PropertyGroup>
  <Generator_EnableComments>true</Generator_EnableComments>
  <Generator_DebugMode>false</Generator_DebugMode>
</PropertyGroup>
  • 或者通过命令行直接传入:
dotnet build -p:Generator_EnableComments=true -p:Generator_DebugMode=true

注意事项

  • AnalyzerConfigOptionsProvider.GlobalOptions中,MSBuild属性的键格式为build_property.{属性名},注意属性名大小写需与项目配置一致。
  • 增量生成器读取的配置是编译时静态值,不会随代码修改动态变化,符合增量生成器的工作机制。
  • 如果需要区分不同文件/项目的配置,可使用AnalyzerConfigOptionsProvider.GetOptions(SyntaxNode)获取特定节点所在项目的配置,大部分场景下GlobalOptions已足够使用。

内容的提问来源于stack exchange,提问作者sanelli

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 00:40:36