基于IncrementalGenerator的源代码生成无法运行问题排查
解决IncrementalGenerator无法运行的问题
问题描述
我参照多个示例(比如Shawn Wildermuth的YouTube视频)尝试实现最基础的IncrementalGenerator,但一直无法正常运行。我创建了两个项目:一个控制台项目和一个生成器项目,项目配置及生成器类代码如下。控制台项目无法识别生成的类,引用时构建失败,但解决方案构建显示成功;生成器类里设置的断点也从未触发。我用的是Visual Studio 2022,请问需要启用或配置哪些内容才能让它正常工作?
控制台项目配置
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>net8.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <Nullable>enable</Nullable> </PropertyGroup> <ItemGroup> <ProjectReference Include="..\ClassLibrary1\ClassLibrary1.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false"/> </ItemGroup> </Project>
生成器项目配置
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>netstandard2.0</TargetFramework> <LangVersion>latest</LangVersion> <EnforceExtendedAnalyzerRules>true</EnforceExtendedAnalyzerRules> </PropertyGroup> <ItemGroup> <PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.11.0"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> </PackageReference> <PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.13.0" /> </ItemGroup> </Project>
生成器类代码
using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp.Syntax; using System.Collections.Immutable; namespace ClassLibrary1; [Generator] public class Class1 : IIncrementalGenerator { public void Initialize(IncrementalGeneratorInitializationContext context) { var provider = context.SyntaxProvider.CreateSyntaxProvider( static (syntaxNode, _) => syntaxNode is ClassDeclarationSyntax, static (ctx, _) => (ClassDeclarationSyntax)ctx.Node) .Where(x => x != null); var compilation = context.CompilationProvider .Combine(provider.Collect()); context.RegisterSourceOutput(compilation, Execute); } private void Execute(SourceProductionContext arg1, (Compilation Left, ImmutableArray<ClassDeclarationSyntax> Right) arg2) { var theCode = """ namespace Generated; public static class GeneratedClass { public static string GetCode() { return "Hello from the generated code!"; } } """; arg1.AddSource("GeneratedClass.g.cs", theCode); } }
解决方案
1. 修正生成器项目的包引用
Microsoft.CodeAnalysis.CSharp包需要设置私有资产,避免运行时依赖冲突,修改后的配置如下:
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.13.0"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> </PackageReference>
2. 标记生成器为Roslyn组件
在生成器项目的PropertyGroup中添加以下配置,确保Visual Studio正确识别这是一个Roslyn生成器:
<IsRoslynComponent>true</IsRoslynComponent>
3. 调整生成器触发逻辑(测试阶段)
当前生成器仅在检测到类声明时才执行,如果控制台项目中没有类,生成器不会触发。可以改为无条件生成代码来测试:
public void Initialize(IncrementalGeneratorInitializationContext context) { // 直接监听编译过程,无条件生成代码 context.RegisterSourceOutput(context.CompilationProvider, (ctx, compilation) => { var theCode = """ namespace Generated; public static class GeneratedClass { public static string GetCode() { return "Hello from the generated code!"; } } """; ctx.AddSource("GeneratedClass.g.cs", theCode); }); }
4. 启用生成器调试
要让断点触发,需要附加到Roslyn编译进程:
- 先执行一次解决方案构建(Ctrl+Shift+B)
- 在Visual Studio中打开“调试”->“附加到进程”
- 找到并附加
VBCSCompiler.exe(C#项目的编译进程,可能有多个,选择最新启动的那个) - 重新构建控制台项目,断点即可触发
5. 验证生成代码是否存在
在控制台项目的解决方案资源管理器中,点击“显示所有文件”,展开obj\Debug\net8.0\generated\ClassLibrary1.Class1目录,查看是否存在GeneratedClass.g.cs:
- 如果存在:说明生成成功,尝试重启Visual Studio刷新IntelliSense
- 如果不存在:说明生成器未触发,检查前面的配置是否正确
6. 清理缓存并重新构建
执行以下步骤清除可能的缓存问题:
- 点击菜单“生成”->“清理解决方案”
- 删除两个项目的
bin和obj目录 - 重新构建整个解决方案
内容的提问来源于stack exchange,提问作者Valyrion
相关产品推荐
相关产品推荐

