我正在尝试使用c#源代码生成器。我花了大约一天的时间,我发现这是一个非常令人沮丧和痛苦的经历。智能感知非常不可靠。它偶尔会起作用,但大多数情况下不会,我还没有找到任何解决方法。(重新启动Visual Studio没有帮助)
但更根本的是,我在调试生成代码中的错误时遇到了很大的麻烦。当我在源生成器的模板中犯了一个错误并尝试编译时,我可能会得到诸如"方法必须有一个返回类型"在生成的文件中。但是,当我双击错误时,它不会将我带到生成的代码。这使得很难看出它有什么问题。
有什么诀窍吗?是否有任何方法来检查生成的代码,当它未能编译?更一般地说,什么时候生成的代码可用于IntelliSense,什么时候不可用?
我使用的是Visual Studio Professional 2022版本17.1.6和ReSharper 2022.1。
提前感谢!
将以下代码添加到代码生成器构造函数代码中:
#if DEBUG
if (!Debugger.IsAttached)
{
Debugger.Launch();
}
#endif
现在可以在Visual Studio中使用断点了。
智能感知在VS的代码生成器中确实是垃圾。你需要关闭VS,删除/bin和/obj文件夹,重新打开VS,然后重建。每次进行更改时都必须这样做。当你修改了一些内容后,VS会显示旧版本,智能感知会将新内容标记为错误,但它仍然会编译并运行…
为了获得更好的体验,我推荐使用Rider,它对代码生成器有更好的集成体验。
我已经找到了解决问题的部分方法。
首先,在使用源代码生成器时不要使用Visual Studio中的ReSharper生成器。它没有给出正确的错误消息。相反,可以从命令行运行dotnet build
。这样可以得到更好的错误消息。
事实上,我的部分问题可能是由于ReSharper的bug或限制(虽然我没有调查过,所以这是纯粹的猜测)。
第二,您可以测试源生成器的内部,而无需在编译时运行源生成器。
- 重构源生成器并提取一个helper类(我们可以将其命名为SourceGeneratorHelper.cs)),它接受您的输入(例如XML)并产生输出(例如StringBuilder)。)。
- 创建一个单独的c#测试项目SourceGeneratorHelperTest.csproj用于测试类SourceGeneratorHelper.cs。在这个项目中,引用你的源生成器项目,就像它是一个常规项目一样——也就是说,不要在项目引用中使用
OutputItemType="Analyzer"
。 现在您可以对源生成器的内部进行单元测试了。你也可以将生成的c#代码转储到一个文件中并检查它。
此外,正如NightOwl888所指出的,我可以将其添加到引用项目中,以便使它将生成的文件吐出来到磁盘(如本文所述):
<PropertyGroup>
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
</PropertyGroup>
我还没有解决智能感知问题,但现在我至少可以忍受使用这个生成器了。