Source Generator 不会自动生效,最常见原因是宿主项目未满足三项硬性条件:使用 Microsoft.NET.Sdk、目标框架≥net5.0、.csproj 中显式引用生成器并设 OutputItemType="Analyzer" 且 ReferenceOutputAssembly="false"。

Source Generator 不会自动生效,哪怕你代码写得完全正确——它只在特定项目结构和配置下被 Roslyn 识别并调用。
为什么 Execute 方法根本没运行?
最常见原因是宿主项目没“认出”生成器。Roslyn 只扫描满足三项硬性条件的引用:
-
Project Sdk="Microsoft.NET.Sdk"(不能是Microsoft.NET.Sdk.Web等子集 SDK,除非显式导入主 SDK) -
<TargetFramework>net5.0</TargetFramework>或更高(netstandard2.0、netcoreapp3.1均不支持) - 宿主项目的
.csproj中必须显式引用生成器项目,并设置:OutputItemType="Analyzer"且ReferenceOutputAssembly="false"
漏掉任意一项,Initialize 和 Execute 都不会被触发,也不会报错,静默失效。
[Generator] 特性写错位置或命名空间就等于没写
这个特性不是装饰用的,它是 Roslyn 扫描生成器类的唯一标记。必须同时满足:
- 放在类声明正前方(不能在
public之后、不能在类体内) - 来自
Microsoft.CodeAnalysis命名空间(不是你自己定义的同名类) - 类本身是
public、非static、非嵌套(public class MyGenerator : ISourceGenerator✅;public static class MyGen❌;public class Outer { public class Inner : ISourceGenerator❌)
手误写成 [generator](小写)、[MyGenerator] 或放在方法上,都会导致整个类被跳过。
在 Execute 里访问语法树和语义模型的常见陷阱
别直接用 context.Compilation.SyntaxTrees[0] 或硬编码索引——多文件项目、Razor 视图、.g.cs 自动生成文件都会打乱顺序。
- 遍历所有语法树应使用
foreach (var tree in context.Compilation.SyntaxTrees) - 获取语义模型必须配对:用
context.Compilation.GetSemanticModel(tree),不能跨 tree 复用 model - 生成的代码必须通过
context.AddSource("FileName.g.cs", SourceText.From(content, Encoding.UTF8))注入;后缀带.g.cs是约定,避免和手写文件重名冲突 - 绝对不要在
Execute中throw异常——会导致编译失败;出错请用context.ReportDiagnostic()发送诊断信息
生成器项目依赖的 Roslyn 版本必须匹配 SDK 内置版本
.NET 6 对应 Roslyn 4.0+,.NET 8 对应 Roslyn 4.8+。生成器项目若引用了错误版本的 Microsoft.CodeAnalysis.CSharp,可能静默失败或类型绑定异常。
- 推荐方式:不手动 NuGet 安装,而是用
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="$(MicrosoftNetSdkMajorMinorVersion).x"这类变量引用(具体看 SDK 文档) - 检查方式:在生成器项目中打开
obj/project.assets.json,确认Microsoft.CodeAnalysis.CSharp的 resolved version 与当前 SDK 的 Roslyn 版本一致 - 混淆点:
Microsoft.CodeAnalysis.Analyzers是辅助包,必须同时引用,但它的版本兼容性更宽松
真正卡住人的地方,往往不是语法或逻辑,而是项目系统层面对“生成器身份”的识别机制——它极其严格,且不报错。只要有一处配置偏离规范,你就永远看不到 Execute 被调用。


















