反射的代价

序列化、对象映射、依赖注入这些框架经常用反射在运行时读类型、创建对象。反射灵活,但每次都要查元数据、做绑定,启动慢、还容易把类型错误拖到运行时才爆。源生成器的思路是:把这些工作挪到编译期,直接生成强类型代码。

能在编译期确定的,就别留到运行时。
反射的三个痛点
  • 启动慢元数据扫描耗时。
  • 类型不安全错误运行时才现形。
  • 裁剪受限反射让 AOT 难裁剪。
源生成器配图:中央发光的齿轮轮廓,周围环绕半透明代码方块与小齿轮
齿轮居中,代码方块环绕它被光链串起。

源生成器是什么

源生成器是一个在编译阶段运行的组件。它可以读取你代码里的语法树、语义模型,然后额外生成一些 .cs 文件一起参与编译。System.Text.Json、Mapperly 这些库已经用它替代了大量反射。

写一个增量源生成器

一个最小源生成器实现 IIncrementalGenerator,注册语法节点或类型的回调,分析后用 SyntaxTree 生成代码。关键是增量——只有相关代码变动才重新生成,别让它拖慢整个编译。

// 伪代码骨架
[Generator]
public class MyGen : IIncrementalGenerator {
  public void Initialize(IncrementalGeneratorContext c) {
    // 注册对带特性类型的分析并emit代码
  }
}

典型应用场景

常见三类:一是序列化替代反射;二是对象映射;三是 INotifyPropertyChanged 这类样板代码自动生成。它们的共同点是——逻辑确定、类型明确,非常适合在编译期写死。

调试与诊断

源生成器生成的代码默认看不见。打开编辑器里的「显示生成器输出」,或在项目里把生成的 .cs 写到磁盘,才能逐行核对它到底生成了什么。生成错了,往往是分析逻辑没考虑到边界类型。

落地建议
  • 先小范围从一个样板代码生成起步。
  • 开增量保证编译速度。
  • 可观测把生成代码落盘核对。