0

0

C# Roslyn操作代码文件 C#如何使用Roslyn API解析和生成C#源文件

幻夢星雲

幻夢星雲

发布时间:2026-03-18 11:58:00

|

473人浏览过

|

来源于php中文网

原创

CSharpSyntaxTree.ParseText需显式指定CSharpParseOptions语言版本,语法节点不可变须赋值接收ReplaceNode返回值,生成代码须用NormalizeWhitespace().ToFullString()并用SyntaxFactory构造合法节点。

c# roslyn操作代码文件 c#如何使用roslyn api解析和生成c#源文件

CSharpSyntaxTree.ParseText 读取源码时,别漏掉 ParseOptions

直接 CSharpSyntaxTree.ParseText("class A {}") 看似能跑,但一遇到 asyncrecordglobal using 就报错:「unexpected token」或语法树不完整。这是因为默认解析器只支持 C# 6 语法,而新版特性需要显式指定语言版本。

  • 必须传入 new CSharpParseOptions(LanguageVersion.CSharp12)(按项目实际版本选)
  • 如果源码含 UTF-8 BOM 或换行符异常,加 encoding: Encoding.UTF8 避免字符解析错位
  • 从文件读取时,优先用 CSharpSyntaxTree.ParseText(File.ReadAllText(path), options),别用 File.ReadAllBytes + Encoding 手动转——容易丢元数据(比如行号映射)

修改语法树后,root.ReplaceNode 不生效?检查是否用了不可变节点

Roslyn 的语法节点全是不可变(immutable)的,ReplaceNode 返回的是新树,原 root 变量没变。常见错误是写了 root.ReplaceNode(old, new) 却没接返回值,后续还拿旧 root 去生成代码,结果什么都没改。

  • 必须赋值: root = root.ReplaceNode(oldNode, newNode)
  • 批量替换用 root.ReplaceNodes,它接收一个 IEnumerable<SyntaxNode> 和转换函数,比循环调 ReplaceNode 安全(避免中间状态污染)
  • 如果要插入新节点(如加字段),别直接 new FieldDeclarationSyntax——得用 SyntaxFactory.FieldDeclaration 系列工厂方法,否则缺少必要的语法令牌(如分号、修饰符顺序)

生成字符串时,root.ToString()root.NormalizeWhitespace().ToFullString() 差在哪

ToString() 只输出原始解析后的文本(缩进乱、缺换行、无空格),根本不能当源码用;ToFullString() 也不行——它保留所有原始空白,但没格式化逻辑。真正可用的是 NormalizeWhitespace() 后再 ToFullString()

Jamboss
Jamboss

Jamboss是一款简单的AI音乐生成App,可以一键生成歌曲。

下载
  • NormalizeWhitespace() 会补全缺失的空格/换行(比如 if(x){}if (x) { }),还能传参控制缩进风格(indentation: " "
  • 若需匹配团队代码风格,建议额外用 Formatter.Format(root, workspace)(需引入 Microsoft.CodeAnalysis.Workspaces),但它依赖 AdhocWorkspace 和文档上下文,轻量脚本里慎用
  • 注意: NormalizeWhitespace 不改变语法结构,只是美化;如果节点本身缺 SemicolonToken,它不会帮你加——得先用工厂方法构造合法节点

引用 Microsoft.CodeAnalysis.CSharp 后,编译报错“找不到类型或命名空间”

常见于 .NET SDK 项目(Sdk="Microsoft.NET.Sdk"),因为 Roslyn 包默认不参与编译引用传递。即使 NuGet 装了,using Microsoft.CodeAnalysis 仍标红。

  • 必须在 .csproj 中显式设 <IncludeSourceGeneratorAttributes>true</IncludeSourceGeneratorAttributes>(非必需,但防坑)
  • 更关键的是加 <PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.9.2" PrivateAssets="all" />,且 PrivateAssets="all" 要保留,否则可能和项目自带的编译器版本冲突
  • 如果用的是 .NET 8+,推荐统一用 Microsoft.CodeAnalysis.Common + CSharp 组合包,别混用 Microsoft.CodeAnalysis(旧全量包,已弃用)

语法树不是字符串拼接,节点关系、令牌位置、语义模型三者咬合很紧。少一个 SyntaxFactory.Token,或者忘了调 WithLeadingTrivia 补注释,生成的代码就可能编译失败——这种细节没报错提示,只能靠调试时看 root.ToFullString() 输出肉眼排查。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
if什么意思
if什么意思

if的意思是“如果”的条件。它是一个用于引导条件语句的关键词,用于根据特定条件的真假情况来执行不同的代码块。本专题提供if什么意思的相关文章,供大家免费阅读。

848

2023.08.22

format在python中的用法
format在python中的用法

Python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

890

2023.07.31

python中的format是什么意思
python中的format是什么意思

python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

467

2024.06.27

登录token无效
登录token无效

登录token无效解决方法:1、检查token的有效期限,如果token已经过期,需要重新获取一个新的token;2、检查token的签名,如果签名不正确,需要重新获取一个新的token;3、检查密钥的正确性,如果密钥不正确,需要重新获取一个新的token;4、使用HTTPS协议传输token,建议使用HTTPS协议进行传输 ;5、使用双因素认证,双因素认证可以提高账户的安全性。

6705

2023.09.14

登录token无效怎么办
登录token无效怎么办

登录token无效的解决办法有检查Token是否过期、检查Token是否正确、检查Token是否被篡改、检查Token是否与用户匹配、清除缓存或Cookie、检查网络连接和服务器状态、重新登录或请求新的Token、联系技术支持或开发人员等。本专题为大家提供token相关的文章、下载、课程内容,供大家免费下载体验。

847

2023.09.14

token怎么获取
token怎么获取

获取token值的方法:1、小程序调用“wx.login()”获取 临时登录凭证code,并回传到开发者服务器;2、开发者服务器以code换取,用户唯一标识openid和会话密钥“session_key”。想了解更详细的内容,可以阅读本专题下面的文章。

1112

2023.12.21

token什么意思
token什么意思

token是一种用于表示用户权限、记录交易信息、支付虚拟货币的数字货币。可以用来在特定的网络上进行交易,用来购买或出售特定的虚拟货币,也可以用来支付特定的服务费用。想了解更多token什么意思的相关内容可以访问本专题下面的文章。

2263

2024.03.01

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

761

2023.08.03

Python WebSocket实时通信与异步服务开发实践
Python WebSocket实时通信与异步服务开发实践

本专题聚焦 Python 在实时通信场景中的开发实践,系统讲解 WebSocket 协议原理、长连接管理、消息推送机制以及异步服务架构设计。内容包括客户端与服务端通信实现、连接稳定性优化、消息队列集成及高并发处理策略。通过完整案例,帮助开发者构建高效稳定的实时通信系统,适用于聊天应用、实时数据推送等场景。

3

2026.03.18

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C# 教程
C# 教程

共94课时 | 11.6万人学习

C 教程
C 教程

共75课时 | 5.6万人学习

C++教程
C++教程

共115课时 | 22.4万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号