Skip to content

第 4 章:最小源生成器骨架

本章目标

  • 认识最小增量生成器骨架
  • 理解 [Generator]IIncrementalGeneratorInitialize(...) 的角色
  • 知道为什么说生成器是在“搭管道”

先看现象

打开主文件:

  • sample/01-tostring-generator/ToStringGenerator/ToStringGenerator.cs

先只看开头:

csharp
[Generator]
public class ToStringGenerator : IIncrementalGenerator
{
    public void Initialize(IncrementalGeneratorInitializationContext context)
    {
        ...
    }
}

这几行虽然短,但已经包含了增量生成器最核心的骨架。

再看代码

[Generator]

它告诉编译器:这是一个生成器类型。

如果少了这个标记,很多情况下编译器不会按源生成器来识别它。

IIncrementalGenerator

它说明这个生成器采用的是增量模型。你现在先不用急着深究“增量”底层细节,只要先知道:

  • 它不是每次都把所有事情从头做一遍
  • 它倾向于把流程拆成多个可缓存步骤

Initialize(...)

这是入口方法,但它不是“直接生成所有代码”的地方,更像“注册后续处理流程”的地方。

你可以把它理解成:

  • 在这里决定要关注什么输入
  • 在这里决定要怎么筛选目标
  • 在这里决定最后把什么数据输出成代码

所以这一步常被形容为“搭管道”。

如何验证

做下面 3 个动作:

  1. 重新阅读 ToStringGenerator.cs 前 40 行
  2. 找出 Initialize(...) 里大致有几段注册逻辑
  3. 用自己的话回答:为什么 Initialize(...) 不是运行时入口?

常见误解

  • 误解 1:Initialize(...) 就是开始真正生成代码的地方
    • 更准确地说,它是注册后续流程的地方
  • 误解 2:生成器和普通 Main() 一样,都是程序入口
    • 不是,生成器入口发生在编译阶段
  • 误解 3:学会骨架就等于学会了生成器
    • 骨架只是开始,真正的难点在后面的输入筛选和代码输出

本章新名词

  • [Generator]
  • IIncrementalGenerator
  • Initialize(...)
  • IncrementalGeneratorInitializationContext

本章小结

最小生成器骨架并不复杂,难点不是骨架本身,而是后续每一步要接什么输入、做什么转换、输出什么结果。

下一章我们先走最短路径:不分析任何用户代码,只先学会生成一份固定源码。

上一章 | 返回主教程目录 | 下一章:固定输出 - 生成特性定义

基于当前仓库文档副本构建的 VitePress 站点