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

如何通过源生成器基于所有转换节点聚合生成源代码文件

基于所有转换节点聚合生成单个源代码文件的解决方案

要实现基于所有MyEnumData聚合生成单个文件,你需要使用Incremental Generator的**Collect()**方法将分散的IncrementalValuesProvider<MyEnumData>转换为IncrementalValueProvider<ImmutableArray<MyEnumData>>,这样就能一次性获取所有转换后的节点数据,再生成单个文件。

具体实现步骤

  • 聚合所有数据:在现有IncrementalValuesProvider<MyEnumData>链后调用Collect()方法,将多个数据项合并为一个不可变数组的增量提供器。
  • 注册单个文件生成逻辑:针对聚合后的增量提供器注册源输出,在处理逻辑中遍历整个数组生成代码。

修改后的完整代码示例

public void Initialize(IncrementalGeneratorInitializationContext context)
{
    // 原有的数据收集与转换逻辑
    IncrementalValuesProvider<MyEnumData?> sources = context.SyntaxProvider
        .ForAttributeWithMetadataName(
            MyEnumAttributeFullName,
            predicate: (node, _) => node is EnumDeclarationSyntax,
            transform: MyTransform)
        .WithTrackingName("Gathering")
        .Where(static node => node is not null)
        .WithTrackingName("RemovingNulls");

    // 聚合所有MyEnumData为单个ImmutableArray
    IncrementalValueProvider<ImmutableArray<MyEnumData>> aggregatedSources = sources.Collect();

    // 注册源输出,处理整个聚合后的数组
    context.RegisterSourceOutput(aggregatedSources, static (context, allEnumData) =>
    {
        ExecuteForAll(context, allEnumData);
    });
}

// 处理所有聚合数据的方法
private static void ExecuteForAll(SourceProductionContext context, ImmutableArray<MyEnumData> allEnumData)
{
    // 在这里编写生成单个文件的逻辑,比如构建注册表代码
    StringBuilder codeBuilder = new StringBuilder();
    codeBuilder.AppendLine("// 自动生成的枚举注册表");
    codeBuilder.AppendLine("public static class EnumRegistry");
    codeBuilder.AppendLine("{");
    codeBuilder.AppendLine("    public static readonly IReadOnlyList<MyEnumData> AllEnums = new List<MyEnumData>");
    codeBuilder.AppendLine("    {");

    foreach (var enumData in allEnumData)
    {
        codeBuilder.AppendLine($"        new MyEnumData(nameof({enumData.EnumName}), {enumData.ValueCount}),");
    }

    codeBuilder.AppendLine("    };");
    codeBuilder.AppendLine("}");

    // 添加生成的源代码文件
    context.AddSource("EnumRegistry.g.cs", codeBuilder.ToString());
}

关键说明

  • Collect()方法:这是Incremental Generator提供的核心聚合API,它会将IncrementalValuesProvider<T>转换为IncrementalValueProvider<ImmutableArray<T>>,确保高效的增量更新——只有当集合中的数据发生变化时,才会重新触发后续的生成逻辑。
  • ImmutableArray:使用不可变数组保证线程安全和增量更新的可靠性,符合源生成器的编译时执行要求。
  • 避免运行时反射:所有数据都是在编译时通过语法分析和转换获取的,完全不需要运行时反射操作,满足性能和设计需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 06:45:16