Incremental Source Generator生成错误代码却编译成功的原因咨询
问题:增量源代码生成器生成看似错误的代码却未触发编译错误的原因
场景复现
项目配置
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>netstandard2.0</TargetFramework> <IsRoslynComponent>true</IsRoslynComponent> <LangVersion>latest</LangVersion> </PropertyGroup> <ItemGroup> <PackageReference Include="Microsoft.CodeAnalysis" Version="4.2.0" /> <PackageReference Include="System.Text.Json" Version="6.0.0" /> </ItemGroup> </Project>
增量源代码生成器代码
[Generator] public class SourceGenerator : IIncrementalGenerator { public void Initialize(IncrementalGeneratorInitializationContext context) { context.RegisterSourceOutput(context.AdditionalTextsProvider, static (context, name) => { string sourceCode = $@" public class {"AAA"}{{ {{ }} "; context.AddSource("AAA" + ".g.cs", sourceCode); }); } }
现象
首次构建解决方案时预期会出现编译错误,但重启Visual Studio后,生成的代码如下:
public class AAA{ { }
查看该AAA.g.cs文件时,文本编辑器未高亮缺少闭合大括号的错误,且第二次构建解决方案成功。
原因分析
你看到的看似有语法错误的代码,实际上是合法的C#语法,具体原因如下:
- 类内部的
{ }是实例初始化块,属于C#的合法语法。这类裸代码块会被编译器自动嵌入到类的所有实例构造函数中(如果没有显式定义构造函数,编译器会生成默认构造函数并包含该块的逻辑)。即使块内没有任何代码,语法本身也是符合规范的。 - 生成的代码结构等价于:
因此编译器不会判定为语法错误,编辑器也不会高亮所谓的“缺少闭合大括号”问题。public class AAA { public AAA() { // 初始化块的内容(此处为空) } } - 首次构建可能出现的异常,大概率是Visual Studio的Roslyn缓存或生成器初始化时机导致的临时问题,重启VS后生成器正常输出了合法代码,后续构建自然成功。
内容的提问来源于stack exchange,提问作者martinrhan
相关产品推荐
相关产品推荐

