【踩坑】Roslyn 5与VS2022——不散的红色浪线

本文地址https://www.cnblogs.com/oberon-zjt0806/p/19429665

目录

首先祝大家2026新年快乐!🎉🐴

先说本文的结论------

Visual Studio 2022的IntelliSense似乎不能和Roslyn 5.0良好配合,导致MSBuild无法加载到生成器构建的代码

如果想在Visual Studio 2022中使用代码分析服务,请确保引用的Nuget包Microsoft.CodeAnalysis的版本为4.x

MSDN文档列举了Roslyn版本与具体IDE的兼容情况,详见这里

另外,如果目标项目的CS0103或者CS0246没有立即褪去,那么你需要关闭报错的文件,清理并重新生成解决方案。

前请提要

昨天想接触一下传说中的源代码生成器(Source Generator),于是就查了一堆资料照猫画虎写了一个------

csharp 复制代码
/// 生成器程序集 SourceGeneratorDemo.Generators
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Text;
using System.Text;

namespace SourceGeneratorDemo.Generators;

[Generator]
public class HelloWorldGenerator : IIncrementalGenerator
{
	public void Initialize(IncrementalGeneratorInitializationContext context)
	{
		// A simple pipeline that always produces a single string
		var helloSource = context.AnalyzerConfigOptionsProvider
			.Select((_, _) => @"
namespace SourceGeneratorDemo.Generated
{
	public class GeneratedProgram
	{
		public static void HelloWorld()
		{
			Console.WriteLine(""Hello from incremental generator!"");
		}
	}
}
");

		context.RegisterSourceOutput(helloSource, (spc, source) =>
		{
			spc.AddSource("GeneratedProgram.g.cs", SourceText.From(source, Encoding.UTF8));
		});
	}
}

显然这个生成器预期产生下面这段代码,一个简单的Hello World类------

csharp 复制代码
namespace SourceGenerator.Generated
{
	public class GeneratedProgram
	{
		public static void HelloWorld()
		{
			Console.WriteLine(""Hello from incremental generator!"");
		}
	}
}

然后安装了Roslyn,也就是Microsoft.CodeAnalysis包。按照项目配置了

xml 复制代码
<TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>latest</LangVersion>
<EnforceExtendedAnalyzerRules>true</EnforceExtendedAnalyzerRules>

然后在目标项目(此时是空的)中引用生成的代码。首先将生成器项目引入------

xml 复制代码
<!-- 目标项目 SourceGeneratorDemo.csproj -->
<ItemGroup>
	<ProjectReference Include="..\SourceGeneratorDemo.HelloWorldGenerator\SourceGeneratorDemo.Generators.csproj" 
					  OutputItemType="Analyzer" 
					  ReferenceOutputAssembly="false" />
</ItemGroup>

我们生成的代码在SourceGenerator.Generated命名空间下,包含一个类GeneratedProgram,带有一个方法void HelloWorld();

csharp 复制代码
// 目标项目 Program.cs
using static System.Console;
using SourceGenerator.Generated;

GeneratedProgram.HelloWorld(); // 直接使用了顶级语句

当写完上面这部分的时候在生成之前,SourceGenerator.GeneratedGeneratedProgram是会标红色波浪线的(前者为CS0246,后者为CS0103),这是正常的,因为生成的代码还没有通过编译器加载到目标项目。所以自然是找不到生成的这些元素的。

按照预期,只要我生成运行整个解决方案,那么Roslyn会调用生成器SourceGeneratorDemo.Generators.HelloWorldGenerator 生成出预期的代码,然后将这段生成的代码加入到目标项目中来。只要我重新打开Program.cs,IntelliSense就应该正确解析SourceGenerator.GeneratedGeneratedProgram这两个符号。

有趣的部分

然而,有趣的部分来了,虽然在生成解决方案之后目标项目被正确构建并且弹出了控制台输出了

text 复制代码
Hello World

但是Program.cs中的红色波浪线依然没有消失!也就是说编辑器还在提示我CS0103和CS0246,也就是IntelliSense还是找不到SourceGeneratorDemo.GeneratedGeneratedProgram。按下F12也不能导航到生成代码下。

在多次重启IDE、清理重新构建项目、删除.vs缓存之后问题仍然存在,在网上搜了半天,没找到有效的解决方法(可能也是我想尽办法也没有描述清楚),于是就开始问Copilot。

Good End

与 Copilot battle了半天(查看需要T子),期间尝试过找茬<ProjectReference>namespace以及<EnforceExtendedAnalyzerRules>等诸多要素。最终确定,问题出在生成器项目的项目文件------

xml 复制代码
<ItemGroup>
	<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="5.0.0" PrivateAssets="all" />
</ItemGroup>

VS2022在安装时自动选择了5.0版本,虽然能正确生成和运行项目,但是与VS2022 IDE使用的Roslyn版本不匹配(Copilot是如此声称的)。

最终我们发现只要把Version改为4.14.0,清理并重新生成解决方案,重新打开Program.cs就不再有问题了。

相关推荐
bkspiderx4 小时前
Visual Studio 2026 新特性全解析(重点聚焦 AI 能力升级)
ide·人工智能·visual studio·vs2026·vs2026新特性全解析·vs2026重点聚焦ai
玩泥巴的21 小时前
如何设计易维护、低学习成本的飞书.NET SDK组件
c#·二次开发·飞书·roslyn
水饺编程1 天前
Visual Studio 软件操作:添加附加依赖项
c语言·c++·windows·visual studio
ChangYan.1 天前
编译报错:此项目需要缓解了 Spectre 漏洞的库。从 Visual Studio 安装程序(单个组件选项卡)为正在使用的任何工具集和体系结构安装它们
ide·visual studio
水饺编程1 天前
开源项目介绍:VirtuaNES 模拟器
c语言·c++·windows·visual studio
C++ 老炮儿的技术栈1 天前
时序数据库 相对于关系型数据库,有什么区别
c语言·开发语言·c++·机器人·时序数据库·visual studio
Lv11770082 天前
初识Visual Studio中的 WinForm
开发语言·ide·笔记·c#·visual studio
持梦远方2 天前
持梦行文本编辑器(cmyfEdit):架构设计与十大核心功能实现详解
开发语言·数据结构·c++·算法·microsoft·visual studio
切糕师学AI3 天前
Visual Studio 内存占用过高问题优化方案
ide·visual studio