本例子依然来自 https://github.com/dotnet/roslyn/wiki/Getting-Started-C%23-Syntax-Transformation , 看过的大神跳过.

修改源码的功能一般常见于各种插件,比如大名鼎鼎的VAX,  本程序的作用也能修改源码, 而且就是修改自己刚打入的代码,  本project里包含两个cs文件, 运行之后会把这两个cs里的部分变量定义改为var. 比如Main函数的这几行, 修改前:

        private static void Main(){SemanticModel model = test.GetSemanticModel(sourceTree);TypeInferenceRewriter rewriter = new TypeInferenceRewriter(model);SyntaxNode newSource = rewriter.Visit(sourceTree.GetRoot());}

修改后

        private static void Main(){var model = test.GetSemanticModel(sourceTree);var rewriter = new TypeInferenceRewriter(model);var newSource = rewriter.Visit(sourceTree.GetRoot());}

好吧, 把完整源码贴出来, 操作步骤跟例子1一样, 在vs2019里先建立 Stand-Alone Code Analysis Tool 工程,再删除只留下空的Main, 确保空Main函数运行不出错的前提下做修改. 建立工程时,项目名称叫TransformationCS,  Main函数所在文件为Program.cs(默认),再建立一个新类名字是: TypeInferenceRewriter , 类文件名字TypeInferenceRewriter.cs,  这两个文件名字程序会用到, 所以要提前说清楚不要修改, 先贴出Program.cs完整内容

using System;
using System.IO;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;namespace TransformationCS
{internal class Program{private static void Main(){Compilation test = CreateTestCompilation();foreach (SyntaxTree sourceTree in test.SyntaxTrees){SemanticModel model = test.GetSemanticModel(sourceTree);TypeInferenceRewriter rewriter = new TypeInferenceRewriter(model);SyntaxNode newSource = rewriter.Visit(sourceTree.GetRoot());if (newSource != sourceTree.GetRoot()){File.WriteAllText(sourceTree.FilePath, newSource.ToFullString());}}}private static Compilation CreateTestCompilation(){String programPath = @"..\..\..\Program.cs";String programText = File.ReadAllText(programPath);SyntaxTree programTree =CSharpSyntaxTree.ParseText(programText).WithFilePath(programPath);String rewriterPath = @"..\..\..\TypeInferenceRewriter.cs";String rewriterText = File.ReadAllText(rewriterPath);SyntaxTree rewriterTree =CSharpSyntaxTree.ParseText(rewriterText).WithFilePath(rewriterPath);SyntaxTree[] sourceTrees = { programTree, rewriterTree };MetadataReference mscorlib =MetadataReference.CreateFromFile(typeof(object).Assembly.Location);MetadataReference codeAnalysis =MetadataReference.CreateFromFile(typeof(SyntaxTree).Assembly.Location);MetadataReference csharpCodeAnalysis =MetadataReference.CreateFromFile(typeof(CSharpSyntaxTree).Assembly.Location);MetadataReference[] references = { mscorlib, codeAnalysis, csharpCodeAnalysis };return CSharpCompilation.Create("TransformationCS",sourceTrees,references,new CSharpCompilationOptions(OutputKind.ConsoleApplication));}}
}

TypeInferenceRewriter.cs 完整内容

using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;namespace TransformationCS
{public class TypeInferenceRewriter : CSharpSyntaxRewriter{private readonly SemanticModel SemanticModel;public TypeInferenceRewriter(SemanticModel semanticModel){this.SemanticModel = semanticModel;}public override SyntaxNode VisitLocalDeclarationStatement(LocalDeclarationStatementSyntax node){if (node.Declaration.Variables.Count > 1) {return node;}if (node.Declaration.Variables[0].Initializer == null){return node;}VariableDeclaratorSyntax declarator = node.Declaration.Variables.First();TypeSyntax variableTypeName = node.Declaration.Type;ITypeSymbol variableType = (ITypeSymbol)SemanticModel.GetSymbolInfo(variableTypeName).Symbol;TypeInfo initializerInfo = SemanticModel.GetTypeInfo(declarator.Initializer.Value);if (variableType == initializerInfo.Type){TypeSyntax varTypeName = IdentifierName("var").WithLeadingTrivia(variableTypeName.GetLeadingTrivia()).WithTrailingTrivia(variableTypeName.GetTrailingTrivia());return node.ReplaceNode(variableTypeName, varTypeName);}else{return node;}}}
}

运行时要留意文件路径问题, 否则提示找不到 , 就是这两行,

String programPath = @"..\..\..\Program.cs";
            String rewriterPath = @"..\..\..\TypeInferenceRewriter.cs";

我把它从 ..\..\ 改成 ..\..\..\ , 因为我的exe文件在debug目录下还有一级, 实际是 \TransformationCS\TransformationCS\bin\Debug\net472 , 所以要做修改, 可能vs2015里没有net472这一级(我没测试过), 所以原作者用了2级目录.  如果实在搞不清, 建议修改为绝对路径.  程序运行完毕后, 就会发现刚写的代码里面有部分变量类型被改为var.

可以用ctrl+z / ctrl+y 来回切换对比看结果.  修改的核心功能就在TypeInferenceRewriter类的VisitLocalDeclarationStatement 里面,

在第一篇Roslyn入门(1):一个简单修改C#代码的例子说过, 这个VisitLocalDeclarationStatement 重载是关于变量声明语句的, 所以传进来的node全是变量声明语句, 变量个数超过1个和没初始化的不管, 其他酌情处理.

Roslyn入门(3): 修改本程序的源码相关推荐

  1. C#网络编程服务器端程序实现源码浅析

    C#网络编程服务器端程序实现源码是怎么样的呢?让我们来看看其中重要的一部分: 由于在此次程序中我们采用的结构是异步阻塞方式,所以在实际的程序中,为了不影响服务器端程序的运行速度,我们在程序中设计了一个 ...

  2. 微信小程序实例源码大全demo下载

    怎么本地测试微信小程序实例源码 1.下载源码 2.打开微信开发者工具 3.添加项目->选择本项目目录->编译执行 微信小程序实例源码大全 微信小程序游戏类demo:识色:从相似颜色中挑选不 ...

  3. java me手机版,一个经典的 JAVA ME 手机程序入门级源码

    一个经典的 JAVA ME 手机程序入门级源码 一个由 Carol Hamer 写的比较有代表性的源码,作者全力推荐,尤其是对于没有 J2ME 开发经验的朋友.自己动手敲出以下贴出的 Hello.ja ...

  4. 外卖优惠券返利系统外卖返利公众号搭建cps系统小程序SaaS源码

    外卖优惠券返利系统外卖返利公众号搭建cps系统小程序SaaS源码 美团/饿了么外卖CPS联盟返利公众号小程序裂变核心源码 源代码地址 https://gitee.com/caonima008/coup ...

  5. 微信小程序github源码大全下载

    微信小程序实例源码大全下载 微信小应用示例代码(phodal/weapp-quick) 源码链接:https://github.com/phodal/weapp-quick 微信小应用地图定位demo ...

  6. 31_ElasticSearch 修改IK分词器源码来基于mysql热更新词库

    31_ElasticSearch 修改IK分词器源码来基于mysql热更新词库 更多干货 分布式实战(干货) spring cloud 实战(干货) mybatis 实战(干货) spring boo ...

  7. 小程序源码整理最新的学习小程序的源码清单包含前后台

    微信小程序疯狂猜成语小程序源码UI美观 知识答题类小程序源码 200多套微信小程序源码带后台+教程+源码 校园小情书小程序前端+后端源码 微信版flappybird小游戏源码下载,经典像素鸟小游戏源码 ...

  8. 帝国cms小程序端源码

    帝国cms小程序版源码系统 后台演示地址:http://etest.xg3.cn/e/admin/ 账号:测试用户 密码:111111 查看详细信息请浏览官网地址:http://e.xg3.cn/ 终 ...

  9. 【520表白】C语言开发《浪漫流星雨》表白程序,源码来了!

    今天是520告白节,特意为大家准备了我去年用C语言表白成功的浪漫表白流星雨项目源码,把这个发给你喜欢的女生,你还害怕520找不到对象,要一个人过吗? 话不多说,直接上效果: 开发环境:Visual S ...

最新文章

  1. 区块链入门之基础知识
  2. 【Java源码分析】ArrayList源码分析
  3. python ioctl_Python如何使用ioctl或spidev从设备读取输入?
  4. 【Android】startActivityForResult()与onActivityResult()与setResult()参数分析
  5. vs2019功能介绍_MFC界面库BCGControlBar v30.0新功能详解:支持VS 2019
  6. c语言程序设计实验报告2,C语言程序设计实验报告2.docx
  7. biztalk BLogs
  8. Numpy中tile函数的用法
  9. 吴恩达|机器学习作业2.0Logistic 回归
  10. php网站用框架与不用的区别,做前端网页是不是必须要用网页框架
  11. 更新尺寸调用什么方法_Java 多线程启动为什么调用 start() 方法而不是 run() 方法?...
  12. 微型计算机原理及应用贾金铃,计算机科学与技术专业本科系列教材·微型计算机原理及应用:理论、实验、课程设计...
  13. oppoA83怎么升级android版本,OPPOA83系统刷机包(官方最新固件升级包正式版-A.37)...
  14. EXCEL公式系列:方差、标准差
  15. 模拟科目二侧方位停车训练
  16. 解读滴滴招股书:提供“移动“价值的全球共享经济企业潜力几何?
  17. Mac电脑怎么远程桌面连接?
  18. dubbo报错Forbid consumer xxxx access service xxx from registryxxx
  19. cv2.imread()和cv2.cvtColor() 的使用
  20. linux里 read函数用法

热门文章

  1. 【乡村振兴】“美在银林”乡村儿童系列公益活动启动暨郭伟新师生公益画展
  2. 魔兽停服:500万寂寞背后的利益暗战
  3. JavaScript基础第05天【笔记+代码】
  4. Windows下使用批处理进行对拍
  5. 脑机接口减肥大法来了!自动减少暴饮暴食频率,无明显副作用|Nature子刊
  6. windows通过bat文件快速启动和关闭redis服务
  7. 园区动态 || 热烈欢迎金牛区五块石街道党群办一行莅临园区考察交流
  8. [S32K]FreeRTOS使用
  9. FMS/wowza/red5/SRS流媒体服务器产品对比
  10. WriteUp--HCTF “php竟如此简单”“影子系统”