.NET Core预构建生成分部类首次编译失败,二次构建正常问题咨询
解决方案:调整MSBuild目标顺序与编译项依赖
问题本质
这个问题的核心是MSBuild的文件收集时机与预构建事件的执行顺序不匹配:
- .NET Core项目在项目加载阶段就会默认收集所有
*.cs文件作为编译项; - 预构建事件(PreBuildEvent)是在项目加载完成后、实际编译(CoreCompile)前执行的,首次构建时生成的分部类文件不会被纳入本次编译的文件列表,导致编译器找不到生成的方法;二次构建时文件已存在,MSBuild能正确收集到,因此编译正常。
你之前尝试的配置无效,是因为<Target BeforeTargets="PreBuildEvent">的执行时机太早,此时MSBuild已经完成了初始编译项的收集;且删除生成文件后,该Target因无触发条件会被跳过,无法重新添加编译项。
可行修复方案
方案1:自定义生成目标并绑定到编译阶段(推荐)
替换原预构建事件为自定义MSBuild Target,明确让编译步骤依赖于分部类文件的生成,确保生成的文件能被即时纳入编译列表:
- 打开项目的
.csproj文件,删除原预构建事件配置,添加以下内容:
<PropertyGroup> <!-- 将自定义生成目标加入编译依赖链 --> <GenerateCompileDependsOn>$(GenerateCompileDependsOn);GeneratePartialClasses</GenerateCompileDependsOn> </PropertyGroup> <Target Name="GeneratePartialClasses" BeforeTargets="CoreCompile"> <!-- 执行原预构建事件中的外部生成器命令,替换成你的实际命令 --> <Exec Command="你的外部生成器路径及参数" /> <!-- 添加生成的分部类文件到编译列表 --> <ItemGroup> <Compile Include="A.g.cs" /> <Compile Include="B.g.cs" /> <!-- 如果是批量生成的文件,可用通配符:Include="*.g.cs" --> </ItemGroup> </Target>
- 保存后重新构建项目/解决方案:
- 这个Target会在实际编译(CoreCompile)前执行,生成文件后立刻将其加入编译项,确保本次编译能包含这些文件;
- 即使删除生成的文件,每次构建前都会执行该Target,不会出现跳过的情况,完美解决首次构建报错的问题。
方案2:强制更新编译项(备选)
若需保留预构建事件,可通过关闭快速最新检查并在预构建后更新编译项来解决:
<PropertyGroup> <EnableDefaultCompileItems>true</EnableDefaultCompileItems> <!-- 关闭快速最新检查,确保MSBuild重新评估所有编译文件 --> <DisableFastUpToDateCheck>true</DisableFastUpToDateCheck> </PropertyGroup> <Target Name="UpdateCompileAfterPreBuild" AfterTargets="PreBuildEvent"> <ItemGroup> <Compile Include="A.g.cs" /> <Compile Include="B.g.cs" /> </ItemGroup> </Target>
注意:此方案会关闭增量构建的快速检查,可能导致构建速度变慢,仅推荐作为临时方案。
解决方案级构建注意事项
若解决方案包含多个依赖项目,需确保所有涉及分部类生成的项目都应用上述配置,避免并行构建时依赖项目先完成编译,导致引用项目找不到生成的方法。
内容的提问来源于stack exchange,提问作者Mirko369
相关产品推荐
相关产品推荐

