c#源代码生成器:如何调试生成代码中的编译器错误?



我正在尝试使用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或限制(虽然我没有调查过,所以这是纯粹的猜测)。

第二,您可以测试源生成器的内部,而无需在编译时运行源生成器

  1. 重构源生成器并提取一个helper类(我们可以将其命名为SourceGeneratorHelper.cs)),它接受您的输入(例如XML)并产生输出(例如StringBuilder)。)。
  2. 创建一个单独的c#测试项目SourceGeneratorHelperTest.csproj用于测试类SourceGeneratorHelper.cs。在这个项目中,引用你的源生成器项目,就像它是一个常规项目一样——也就是说,不要在项目引用中使用OutputItemType="Analyzer"
  3. 现在您可以对源生成器的内部进行单元测试了。你也可以将生成的c#代码转储到一个文件中并检查它。

此外,正如NightOwl888所指出的,我可以将其添加到引用项目中,以便使它将生成的文件吐出来到磁盘(如本文所述):

<PropertyGroup>
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
</PropertyGroup>

我还没有解决智能感知问题,但现在我至少可以忍受使用这个生成器了。

最新更新