【问题标题】:C# Source code generator dependent on existing class依赖于现有类的 C# 源代码生成器
【发布时间】:2022-01-01 05:23:45
【问题描述】:

我需要生成将继承自我的项目中已经存在的抽象类的源代码,并且源代码生成器项目本身会编译。但是当编译器抱怨生成的源不能识别抽象类时,即使它在同一个项目中。我是否需要以某种方式告诉生成器项目对其自身具有运行时依赖项?

编辑: 我正在使用 Microsoft.CodeAnalysis.CSharp。这是描述该站点的代码: https://github.com/alebo611/csharpsourcegenproblem/tree/main/MyGeneratorProject

也就是说,我只想生成一个已经定义的“Vehicle”的子类。如果你在 Visual Studio 中运行它,你会得到以下错误:

错误 CS0246 找不到类型或命名空间名称“Vehicle”(您是否缺少 using 指令或程序集引用?) Consumer generated.cs

并且添加“Using ApplicationContext”并没有帮助,它会抱怨它没有找到上下文。

【问题讨论】:

  • 生成的类中是否导入了命名空间?您可以编辑您的问题并将生成的代码与您想要继承的抽象类一起添加吗?
  • 如果你能发布完整的复制,那就太好了。至少可以请您添加错误本身吗?
  • 您是否缺少 Using 语句。
  • 你使用什么代码生成?如果您使用 CodeDOM 并在内存中编译,则需要通过为每个引用调用 CompilerParameters.ReferencedAssemblies.Add() 来告诉编译器在哪里查找程序中的所有引用。
  • 你设置了ReferenceOutputAssembly="false",就是说源生成器项目的Vehicle类在消费者项目中没有被引用。尝试忽略它或将其设置为true

标签: c# code-generation


【解决方案1】:

源代码生成器用于生成新的源代码,然后将其编译并添加到您的程序集中。这意味着通常只在构建时才需要源生成器程序集。因此,当通过ProjectReference 使用源生成器时,通常使用OutputItemType="Analyzer"ReferenceOutputAssembly="false"

<ProjectReference Include="SourceGenerator.csproj"
                  OutputItemType="Analyzer"
                  ReferenceOutputAssembly="false" />

但是,在您的示例中,源生成器程序集包含使用程序集所需的类型 Vehicle。这意味着源生成器程序集必须被消费者引用,因此您必须省略ReferenceOutputAssembly 参数:

<ProjectReference Include="SourceGenerator.csproj"
                  OutputItemType="Analyzer" />

很遗憾,消费者必须注意生成器的这些细节。幸运的是,通过包使用源生成器时情况有所不同。在这种情况下,包作者会注意将构建时所需的程序集存储在包内的analyzers/dotnet/cs 中,而运行时所需的程序集存储在lib/[targetframework] 中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-24
    • 1970-01-01
    • 1970-01-01
    • 2021-09-04
    • 2014-12-11
    • 2022-11-24
    相关资源
    最近更新 更多