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

C# source generators: How to debug compiler errors in the generated code?

我正在试验 C# source generators。我花了大约一天的时间,我发现这是一次非常令人沮丧和痛苦的经历。 IntelliSense 极其不可靠。它偶尔会工作,但大多数情况下不会,而且我还没有弄清楚它的任何系统。 (重新启动 Visual Studio 没有帮助。)

但更根本的是,我在调试生成的代码中的错误时遇到了很大的麻烦。当我在源代码生成器中的模板中出错并尝试编译时,我可能会在生成的文件中出现类似“方法必须具有 return 类型”的错误。但是当我双击错误时,它并没有带我到生成的代码。这使得很难看出它有什么问题。

有什么技巧吗?编译失败时有没有办法检查生成的代码?更一般地说,生成的代码何时可用于 IntelliSense 以及何时不可使用

我正在使用 Visual Studio Professional 2022 版本 17.1.6 和 ReSharper 2022.1。

提前致谢!

我找到了解决问题的部分方法。

首先,在使用源代码生成器时,不要在 Visual Studio 中使用 ReSharper 构建器。它不会给出正确的错误消息。相反,从命令行 运行 dotnet build。这样你会得到更好的错误信息。

事实上,我的部分问题可能是由于 ReSharper 中的错误或限制引起的(虽然我没有对此进行调查,所以这纯属猜测)。

其次,您可以测试源代码生成器的内部结构,而无需 运行编译时生成源代码

  1. 重构您的源代码生成器并提取一个助手 class(我们可以称之为 SourceGeneratorHelper.cs)来获取您的输入(例如 XML ) 并产生输出(例如 StringBuilder).
  2. 制作一个单独的 C# 测试项目 SourceGeneratorHelperTest.csproj 用于测试 class SourceGeneratorHelper.cs。在此项目中,将您的源代码生成器项目作为常规项目来引用 - 即,不要在您的项目引用中使用 OutputItemType="Analyzer"
  3. 现在您可以对源代码生成器的内部进行单元测试。您还可以将生成的 C# 代码转储到文件并检查它。

此外,正如 NightOwl888 指出的那样,我可以将其添加到引用项目中,以便将生成的文件吐出到磁盘( as explained in this article):

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

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