如何在 Visual Studio 中运行 C# 源代码生成器?

问题描述

最近我正在更新我的自我以学习这项新技术,但是即使我按照教程一步一步来,我也无法运行源代码生成器。

我做了什么:

  1. 使用控制台应用程序创建解决方案,然后添加类库项目。两个项目都是 .NET 5。

  2. 为两个项目安装 NuGet 包 Microsoft.CodeAnalysis.CSharp.Workspaces

  3. 在类库项目中,编写如下代码

    using Microsoft.CodeAnalysis;
    using Microsoft.CodeAnalysis.Text;
    using System.Text;
    
    namespace ClassLibrary {
        [Generator]
        public class MySourceGenerator : ISourceGenerator {
            public void Execute(GeneratorExecutionContext context) {
                context.AddSource("myGeneratedFile.cs",SourceText.From(@"
    namespace Generatednamespace
    {
        public class GeneratedClass
        {
            public static void GeneratedMethod()
            {
                // generated code
            }
        }
    }",Encoding.UTF8));
            }
    
            public void Initialize(GeneratorInitializationContext context) {
            }
        }
    }
    
  4. 在控制台应用程序的 Main 方法中,编写如下代码

                Generatednamespace.GeneratedClass.GeneratedMethod();
    
  5. 在控制台应用程序的 .csproj 中,添加以下代码

      <ItemGroup>
        <ProjectReference Include="..\ClassLibrary_ExperimentalSourceGenerator\ClassLibrary_ExperimentalSourceGenerator.csproj"
                          OutputItemType="Analyzer"
                          ReferenceOutputAssembly="false" />
      </ItemGroup>
    
  6. 构建解决方案。

  7. 收到以下错误

    CS0103
    当前上下文中不存在名称“Generatednamespace” ConsoleApp1 D:\OneDrive\VS Solutions\ConsoleApp1\Program.cs

    以及以下警告:

    CS8032
    无法从 D:\OneDrive\VS Solutions\ClassLibrary_ExperimentalSourceGenerator\bin\Debug\net5.0\ClassLibrary_ExperimentalSourceGenerator.dll 创建分析器 ClassLibrary.MySourceGenerator 的实例:无法加载文件或程序集“System.Runtime,Version=5.0.0.0, Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a' 或其依赖项之一。系统找不到指定的文件

解决方法

我认为这里的问题在于您的源代码生成器程序集针对 .NET 5。

源代码生成器必须以 netstandard2.0 为目标,才能在 Visual Studio 中正常工作。这是因为 VS 在内部运行 net48,因此它无法加载针对较新框架的代码。

这里的提示是错误信息:

无法加载文件或程序集“System.Runtime,Version=5.0.0.0...”

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...