源代码生成器的高级惯用法:增量生成、缓存与持久化状态
超越入门教程,介绍如何构建增量式源代码生成器、使用管道避免重复编译,以及如何持久化状态提高 IDE 响应速度。 · 难度:入门 · +10XP
源代码生成器的高级惯用法:增量生成、缓存与持久化状态
大多数教程只展示简单的生成器,但实际项目中需要处理增量编译、语法树变化检测和状态持久化。本主题详细讲解如何实现 IIncrementalGenerator,利用 IncrementalValueProvider 和 IncrementalValuesProvider 缓存语法节点,避免每次按键都重新生成。我们还会实现一个自定义缓存机制,将生成的代码哈希存入项目文件,仅在输入变化时重新生成。同时讨论如何避免生成器导致 IDE 卡顿,以及如何使用 Microsoft.CodeAnalysis.CSharp 的语法工具进行细粒度过滤。
[Generator]
public class MyIncrementalGenerator : IIncrementalGenerator
{
public void Initialize(IncrementalGeneratorInitializationContext context)
{
var classes = context.SyntaxProvider.ForAttributeWithMetadataName(
"MyAttribute",
(node, _) => node is ClassDeclarationSyntax,
(ctx, _) => ctx.TargetNode as ClassDeclarationSyntax);
context.RegisterSourceOutput(classes, (spc, cls) =>
{
spc.AddSource($"{cls.Identifier}.g.cs", GenerateCode(cls));
});
}
}