Roslyn入门(1):一个简单修改C#代码的例子
网上其他例子都写得有点难懂, 这里有个简单的, 首先你要装好 roslyn, 如果没有安装,打开vs2019的安装程序,点修改,选择如下图进行安装:
我已经在vs2019里面装了, 所以创建项目时出现下图:
选择如图Stand-Alone Code Analysis Tool, 创建项目, 框架选.Net 4.7.2, 但是不知道什么原因,创建出来的项目运行不了,对初学者来说太麻烦,也懒得找原因.
于是删除原来的代码, 只保留空的Main函数. 保留原来的using , 如下所示:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Build.Locator;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.MSBuild;
using Microsoft.CodeAnalysis.Text;namespace TestMyRewriter
{class Program{static async Task Main(string[] args){Console.WriteLine("Hello world");}}
}
保证这个Main能正常运行后, 把程序完整填写:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Build.Locator;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.MSBuild;
using Microsoft.CodeAnalysis.Text;namespace TestMyRewriter
{class Program{static async Task Main(string[] args){ //原始代码string strCode = @"public class Foo{public string _bar = ""baz""; public string strHello = ""heloo world"";}";var tree = CSharpSyntaxTree.ParseText(strCode);var Mscorlib = MetadataReference.CreateFromFile(typeof(object).Assembly.Location);var compilation = CSharpCompilation.Create("MyCompilation",syntaxTrees: new[] { tree }, references: new[] { Mscorlib });// 获得语义模型var model = compilation.GetSemanticModel(tree);var root = model.SyntaxTree.GetRoot();// 用Visit重写代码var rw = new LiteralRewriter();var newRoot = rw.Visit(root);// 新生成代码string strNewCode = newRoot.GetText().ToString();Console.WriteLine(strNewCode);Console.ReadLine();}}class LiteralRewriter : CSharpSyntaxRewriter // 继承CSharpSyntaxRewriter{public override SyntaxNode VisitLiteralExpression(LiteralExpressionSyntax node) // 重载 VisitLiteralExpression 方法, 输入节点是 文字表达式{ if (!node.IsKind(SyntaxKind.StringLiteralExpression)){ return base.VisitLiteralExpression(node); }// 重新构造一个字符串表达式var retVal = SyntaxFactory.LiteralExpression(SyntaxKind.StringLiteralExpression,SyntaxFactory.Literal("NotBaz"));return retVal;}}}
运行结果如下:
这段代码简要解释就是: 用roslyn的语法树工具, 构造一个根节点, 用CSharpSyntaxReWriter重写里面的部分代码, 原始代码就是Main函数里strCode字符串, 重写的办法是自己写一个类继承CSharpSyntaxReWriter, 里面所有以Visit开头的函数都可以重载, 比如VisitLiteralExpression解决字符串表达式, 入口参数node里面只有字符串, 且有多少个字符串就调用这个函数多少次. 现在我重载里非常简单粗暴, 只要是字符串我就改成"NotBaz" .
但是我们还想知道其他的重载函数做什么的, 几十个重载函数, 文档根本没写清楚, 好多生僻词, 这些计算机文法语法分析的专业词, 一般字典查不清楚,只能知道大概, 或者说吃不准确切含义. 简单办法就是重载,用Console.WriteLine大法. 不断修改strCode里的代码内容,会看到各个重载里显示不同的东西, 当然有些内容你的代码块里没有,重载也不会调用到, 代码示例:
public override SyntaxNode VisitArgument(ArgumentSyntax node){Console.WriteLine("ArgumentSyntax:{0}", node.GetText());return base.VisitArgument(node);}public override SyntaxNode VisitArgumentList(ArgumentListSyntax node){Console.WriteLine("ArgumentListSyntax:{0}", node.GetText());return base.VisitArgumentList(node);}public override SyntaxNode VisitVariableDeclaration(VariableDeclarationSyntax node){Console.WriteLine(node.Variables.First().Initializer.Value );return base.VisitVariableDeclaration(node);}
现在稍微搞清楚的有: VisitArgument, 参数, VisitArgumentList 参数列表 VisitLiteralExpression 文字表达式(还不清楚和StringLiteralExpression的确切差别), VisitIdentifierName 标识符名字(包括各种关键字和变量名) VisitVariableDeclaration 变量声明表达式VisitVariableDeclarator 变量本身
这一行里: Console.WriteLine(node.Variables.First().Initializer.Value );
Initializer.Value就是变量初始化的值, 如果没初始化Initializer会是Null,直接调用Value会导致异常. (说人话就是 int a=10; 初始化了就ok, 只写个 int a; 它的Initializer就会是null)
我也是初学,很多东西还在摸索中,先记录下来做个笔记.
参考链接: https://johnkoerner.com/csharp/using-a-csharp-syntax-rewriter/
Roslyn入门(1):一个简单修改C#代码的例子相关推荐
- Unity入门——实现一个简单的跑酷游戏(资源预制)
Unity入门--实现一个简单的跑酷游戏 资源预制 一款跑酷游戏,需要大量重复的场景资源,比如道路.障碍物等,无论是从游戏体验的角度还是运行效率的角度考虑,都不应该全部事先摆好,而是应该由代码随机生成 ...
- 分析一个简单的汇编代码
分析一个简单的汇编代码 部分常见的寄存器 寄存器 16位 32位 64位 累加寄存器 AX EAX RAX 基址寄存器 BX EBX RBX 计数寄存器 CX ECX RCX 数据寄存器 DX EDX ...
- Web Service入门简介(一个简单的WebService示例)
一.Web Service简介 1.1.Web Service基本概念 Web Service也叫XML Web Service WebService是一种可以接收从Internet或者Intrane ...
- 用C语言实现一个简单的计算器代码
#include <stdio.h> #include <math.h> #include <stdlib.h> //预处理指令 int main(void) {d ...
- unity入门——实现一个简单的跑酷游戏(人物控制)
unity入门--实现一个简单的跑酷游戏 场景搭建 将人物放置于世界坐标的(0,0.1,0),初始道路放置于人物脚下,坐标设置为(0,0,0),水面初始位置设置为(0,-2,-100),可以自行调整, ...
- java 序列化 例子_一个简单的Java序列化的例子
简单来说序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化,流的概念这里不用多说(就是I/O),我们可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间(注:要想将对 ...
- 一个简单的 Hello world! 例子使用 boost::mpi::group 和 boost::mpi::broadcast()
一个简单的 Hello world! 例子使用 boost::mpi::group 和 boost::mpi::broadcast 实现功能 C++实现代码 实现功能 一个简单的 Hello worl ...
- 一个简单的XML文档例子
一个简单的XML文档例子: <?xml version="1.0"?> <note> <to>Tove</to> <from& ...
- 一个简单的HTTP通讯的例子,使用了CInternetSession,CHttpConnection,CHttpFile三个类
一个简单的HTTP通讯的例子,使用了CInternetSession,CHttpConnection,CHttpFile三个类. http://blog.csdn.net/STK_tianwen/ar ...
- 20. [Python GUI] PyQt5中的模型与视图框架-实现一个简单的文件浏览器的例子
PyQt5中的模型与视图框架-实现一个简单的文件浏览器的例子 一.使用模型/视图实现一个简单的文件浏览器 二.小手一抖,点个赞再走哦~ 一.使用模型/视图实现一个简单的文件浏览器 这个例子里不涉及数据 ...
最新文章
- 趁ofo退出美市场 Uber不计成本发展共享单车
- java中jtextfield_java中的JTextField
- Java期末复习——ch02基本类型(进制转换,数据类型转换,汉字编码)
- java解决跨域问题
- 在一颗度为4的树T中,若有20个度为4的结点,10个度为3的结点,1个度为2的结点,10个度为1的结点,则树T的叶结点个数是( )
- php cli swoole mysql_[了解实践]Swoole、PHP与MySQL:连接池,swoole扩展实现真正的PHP数据库连接池。...
- Docker集群的创建与管理
- PyCharm代码区不能编辑的解决办法
- 勒索病毒自救在线工具
- 安鸾渗透实战平台--综合渗透--企业网站渗透流程
- PKPM结构设计软件案例教学
- PTAM在Linux下编译运行
- 安川ga700变频器故障码集_安川变频器CPF故障码集
- 【C语言题解】将数字金额翻译成中文大写金额
- php 使用 谷歌验证器
- word实用技巧--学一个记一个
- Markdown转Word文档在线工具
- 你打英雄联盟or王者荣耀为什么老是匹配到怨种队友,进来看
- 访问和更新Orkut数据
- 小觅深度相机kalibr标定
热门文章
- QQ文件保险柜与Truecrypt之对比.
- Android SDK Platform Tools下载(包括adb 、 fastboot 和 systrace)
- kindle看pdf乱码,Kindle中文乱码问题解决办法
- [算法导论] 邮递员问题代码c++实现,Floyd算法+dp,求遍历所有边回到起点的最短路径
- lisp调用布置天正的图块_为啥天正电气图块插到原建筑条件图里显示特别小,高手指点下哈!...
- 【HighCharts系列教程】七、导出属性——exporting
- java 原子量_Java多线程-新特征-原子量
- Windows and CentOS IPv4转IPv6隧道方法
- 爬虫CASE01:反爬策略之使用随机user-agent模拟浏览器的网页爬取
- 三维空间点到原点距离python_如何计算三维空间中两点之间的距离?