VS与Rider中C#源代码生成文件报错或被忽略问题排查
问题分析与解决方案
问题概述
我在使用C#源代码生成器时遇到以下问题:
- 生成的
state.Text.g.cs文件在Visual Studio和Rider中要么被忽略,要么报CS1001“缺少标识符”错误;但将该文件复制出来脱离生成器后,单元测试可正常运行。 - 修改生成代码的命名空间添加
gen.前缀后,报错变为CS0246“找不到命名空间或类型”,且IDE界面无错误提示,仅构建日志中显示错误。 - 同时构建时出现CS8669警告,提示生成代码缺少显式的#nullable指令。
相关配置与报错信息
单元测试项目csproj
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>net7.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <Nullable>enable</Nullable> <IsPackable>false</IsPackable> <IsTestProject>true</IsTestProject> </PropertyGroup> <ItemGroup> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.5.0" /> <PackageReference Include="NUnit" Version="3.13.3" /> <PackageReference Include="NUnit3TestAdapter" Version="4.4.2" /> <PackageReference Include="NUnit.Analyzers" Version="3.6.1" /> <PackageReference Include="coverlet.collector" Version="3.2.0" /> <ProjectReference Include="..\TaskReward.Expander\TaskReward.Expander.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" /> </ItemGroup> <ItemGroup> <AdditionalFiles Include="StateMachineTests\Text.xstate" /> </ItemGroup> </Project>
生成器项目csproj
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>netstandard2.0</TargetFramework> <LangVersion>Latest</LangVersion> <Nullable>enable</Nullable> <EnforceExtendedAnalyzerRules>true</EnforceExtendedAnalyzerRules> </PropertyGroup> <ItemGroup> <PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4" PrivateAssets="all" /> <PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.6.0" PrivateAssets="all" /> </ItemGroup> <ItemGroup> <!-- Generator dependencies --> <PackageReference Include="Newtonsoft.Json" Version="12.0.2" PrivateAssets="all" GeneratePathProperty="True" /> </ItemGroup> <PropertyGroup> <GetTargetPathDependsOn>$(GetTargetPathDependsOn);GetDependencyTargetPaths</GetTargetPathDependsOn> </PropertyGroup> <Target Name="GetDependencyTargetPaths"> <ItemGroup> <TargetPathWithTargetPlatformMoniker Include="$(PKGNewtonsoft_Json)\lib\netstandard2.0\Newtonsoft.Json.dll" IncludeRuntimeDependency="false" /> <!-- Pack both our DLL and the dependencies into a generated Nuget Package --> <None Include="$(OutputPath)\$(AssemblyName).dll" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false" /> <None Include="$(PKGNewtonsoft_Json)\lib\netstandard2.0\Newtonsoft.Json.dll" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false" /> </ItemGroup> </Target> </Project>
构建报错(中文翻译)
构建失败。 "...\GeneratorUnitTestProject\GeneratorUnitTestProject.csproj" (生成目标) (1) -> (CoreCompile 目标) -> ...\GeneratorUnitTestProject\...\....Gen.State.Statemachines\state.Text.g.cs(172,106): 警告 CS8669: 可为空引用类型的注释只能在 #nullable 注释上下文内的代码中使用。对于自动生成的代码,源文件中需要显式的 #nullable 指令。 "...\GeneratorUnitTestProject\GeneratorUnitTestProject.csproj" (生成目标) (1) -> (CoreCompile 目标) -> ...\GeneratorUnitTestProject\StateMachineTests\MachineTest.cs(1,7): 错误 CS0246: 找不到类型或命名空间名称“gen”(是否缺少 using 指令或程序集引用?) 1 个警告 1 个错误
解决方案
1. 修复CS8669警告(基础前提)
在生成器输出的代码开头添加#nullable enable指令,因为测试项目已经启用了<Nullable>enable</Nullable>,生成代码必须显式声明可空上下文,否则会触发警告,甚至可能干扰编译逻辑。
修改生成器的代码生成逻辑,确保每个输出的.g.cs文件开头包含:
#nullable enable
2. 确保生成文件被正确纳入编译
添加配置确保所有生成的.g.cs文件被项目编译包含,在单元测试项目的csproj中加入:
<ItemGroup> <Compile Include="**/*.g.cs" /> </ItemGroup>
这会强制项目编译所有子目录下的.g.cs文件,避免IDE或构建系统忽略生成的代码。
3. 验证命名空间与引用匹配
- 检查
state.Text.g.cs中的命名空间是否确实为gen.xxx(比如gen.State.Statemachines),确保生成逻辑没有拼写错误。 - 在测试文件
MachineTest.cs顶部添加对应的using指令:
或者直接使用完整命名空间引用生成的类型。using gen.State.Statemachines;
4. 清理缓存并重新构建
删除单元测试项目和生成器项目的bin、obj目录,然后重新构建解决方案,避免旧的缓存文件干扰编译结果。
5. 调试生成器输出内容
临时修改生成器,将代码输出到项目根目录的可见位置,对比“能正常运行的复制文件”和生成器实时输出的文件内容,检查是否存在:
- 生成的代码有语法错误(比如CS1001对应的标识符缺失)
- 生成过程中内容截断或不完整
- 命名空间、类型名的拼写差异
6. 检查IDE的代码生成器设置
- Visual Studio:开启“显示所有文件”,查看生成的
.g.cs文件是否存在,是否被标记为“生成的代码”。如果文件不存在,检查生成器类是否正确标注了[Generator]特性并继承自ISourceGenerator。 - Rider:进入
设置→Build, Execution, Deployment→Compiler→Roslyn Analyzers,确保你的生成器被启用。
内容的提问来源于stack exchange,提问作者Drachencheat
相关产品推荐
相关产品推荐

