Microsoft Roslyn是微软.NET“编译器即服务(Compiler as a Service)”的主要产品,它提供了开放的编译器API,并为源代码产生、分析和重构提供了新一代的语言对象模型。Anders Hejlsberg在BUILD 2013大会上提到,C# 6.0的编译器将使用Roslyn实现,这一实现会包含在Visual Studio 2013之后的产品中。根据Anders的描述,C# 6.0的编译器将采用C#开发,从而告别现有的本机代码(native code)的实现方式,“虽然是采用C#来实现C#编译器,但我想性能至少不会比原来的实现方式差。”

有关Roslyn的内容,可以参考以下链接:

让我们先睹为快,了解一下Roslyn的一个具体应用:提取C#和VB.NET代码中的字符串常量。

字符串常量的提取

先看下面的一段代码:

using System;
using System.Collections;
using System.Linq;
using System.Text; namespace HelloWorld
{
class Program
{
static void Main(string[] args)
{
// Output a "greeting" string
Console.WriteLine("Hello, World!");
// Output another "say hello" string
Console.WriteLine("Hi, nice to meet you!");
}
}
}

很明显这段代码中有四个字符串:greeting、Hello, World!、say hello和Hi, nice to meet you!,或许我们可以通过正则表达式来提取这些字符串,但请注意:这些字符串中有两个是在注释语句中出现的,而不是我们所需要的字符串常量。我们只需要得到其中真正用于可执行代码的Hello, World!和Hi, nice to meet you!,这如果通过正则表达式来区分还是有一定难度的,而且对于字符串中的转义字符等特殊字符的判断和提取,正则表达式也略显麻烦。

现在,让我们用Roslyn来完成这一工作。首先,打开Visual Studio 2012/2013,新建一个控制台程序(Console Application),.NET Framework的版本选用4.5或者4.5.1。然后,在新建的控制台程序项目上单击右键,选择Manage NuGet Packages菜单项(注意:.NET Framework的版本必须是4.5以上):

在打开的对话框中,搜索Roslyn,并将Roslyn安装到项目中:

首先创建一个语法树的访问者,它继承于Roslyn.Compilers.CSharp.SyntaxWalker,用于遍历访问C#的语法树,它的实现如下:

class ExtractStringLiteralVisitor : SyntaxWalker
{
readonly List<string> literals = new List<string>();
public override void VisitLiteralExpression(LiteralExpressionSyntax node)
{
if (node.Kind == SyntaxKind.StringLiteralExpression)
literals.Add(node.ToString());
base.VisitLiteralExpression(node);
} public IEnumerable<string> Literals { get { return literals; } }
}

然后,将上面第一段代码文本保存到一个名为source的字符串变量中(当然实际应用中也可以从文件读入源代码),并使用SyntaxTree产生语法树对象,之后使用上面的ExtractStringLiteralVisitor从根部对语法树进行遍历。由于重写的VisitLiteralExpression方法中保存了被访问的文本节点,因此,当Visitor完成遍历之后,即可通过Literals属性获得所有的字符串常量。

var syntaxTree = SyntaxTree.ParseText(source);
var root = syntaxTree.GetRoot();
var visitor = new ExtractStringLiteralVisitor();
visitor.Visit(root);
foreach (var literal in visitor.Literals)
Console.WriteLine(literal);

程序输出如下:

当然还可以使用root.DescendantNodes方法来简化上面的过程。我在例子中使用Visitor的目的就是为了体现Roslyn的语法解析功能。

对VB.NET语言的应用

上面的输入代码是一段C#的程序,如果是VB.NET的源代码,其实处理过程是一样的,无非就是将引用的命名空间从Roslyn.Compilers.CSharp改为Roslyn.Compilers.VisualBasic。注意:Roslyn.Compilers.CSharp和Roslyn.Compilers.VisualBasic下都有SyntaxTree等类型的定义,但这些类型都是独立的,并非从某个基类继承或实现了某些接口,在实际应用中还得注意这点。

应用场景的思考

Roslyn的应用场景应该还是很多的,比如大家熟悉的FxCop,能够根据一些规则来检测托管程序集是否满足这些规则,以保证质量。但FxCop很局限,它需要使用反射,并根据程序集的调试信息PDB文件进行规则判断,而对于源代码本身的规范校验就不太适用了。仔细思考,Roslyn却能够在保证源代码编写规范方面,起到一定的作用。比如:

  • 对定义的变量名、函数名等进行拼写检查
  • 检查注释语句中的拼写错误
  • 检查变量、函数等的命名规范
  • XML文档的自动化翻译(可以借助Bing Translate、Google Translate的API实现自动化翻译),等等

大家也可以在实际中总结一些能够使用Roslyn的场景,我想只要合理利用,一定能在实际工作中帮助我们提高效率,做到事半功倍。

使用Microsoft Roslyn提取C#和VB.NET源代码中的字符串常量的更多相关文章

  1. ActiveX数据对象之事务控制在VB和DELPHI中的应用

            本文发表在中国人民解放军"信息工程大学"学报 2001年第3期.        ActiveX数据对象之事务控制在VB和DELPHI中的应用             ...

  2. Office系列---将Office文件(Word、PPT、Excel)转换为PDF文件,提取Office文件(Word、PPT)中的所有图片

    将Office文件转换为PDF文件,提取Office文件中的所有图片 1.Office系列---将Office文件(Word.PPT.Excel)转换为PDF文件 1.1 基于Office实现的解决方 ...

  3. 4步解决“Microsoft Office Professional Plus 2013在安装过程中出错”

    公司新搭建了AD域,公司内使用了1年多的电脑,现在要加入域,加域过程问题错综复杂. 其中一台电脑上,反应说Excel经常卡住,严重影响使用,所以考虑重装office2013.在控制面板卸载了: 卸载完 ...

  4. JDBC程序优化--提取配置信息放到属性文件中

    JDBC程序优化--提取配置信息放到属性文件中 此处仅仅优化JDBC连接部分,代码如下: public class ConnectionFactory { private static String ...

  5. PHP 正则表达式匹配 img ,PHP 正则提取或替换图片 img 标记中的任意属性。

    PHP正则提取或替换img标记属性 PHP 正则表达式匹配 img ,PHP 正则提取或替换图片 img 标记中的任意属性.   1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ...

  6. 利用Roslyn把C#代码编译到内存中并进行执行

    Tugberk Ugurlu在其博文<Compiling C# Code Into Memory and Executing It with Roslyn>中给大家介绍了一种使用.NET下 ...

  7. vb安装过程中 ntvdm.exe[9696]中发生未处理的win32异常

    最近电脑总是出问题导致我的学习效率很低,前几天在用VB6.0的时候有个知识点不太熟悉,于是按F1发现不会出来帮助文档.突然想到重新装系统之后忘记了安装MSDN帮助插件,就在我安装这个软件的时候发现电脑 ...

  8. Office系列(2)---提取Office文件(Word、PPT)中的所有图片

    回顾一下上文结尾的问题:如何给文档设置一个合适的封面图?其中一个解决方案就是,获取Office文件内部的图片作为封面.这里就详细介绍下获取图片的几种方式,以及他们各自的优缺点. PS:因为之前用VST ...

  9. VB.Net 2010中 ./和../的含义

    文件路径 文件路径就是文件在电脑(服务器)中的位置,表示文件路径的方式有两种:相对路径和绝对路径. Windows由于使用 斜杆/ 作为DOS命令提示符的参数标志了,为了不混淆,所以采用 反斜杠\ 作 ...

随机推荐

  1. 什么情况下才要重写Objective-C中的description方法

    特别注意: 千万不要在description方法中同时使用%@和self,同时使用了%@和self,代表要调用self的description方法,因此最终会导致程序陷入死循环,循环调用descrip ...

  2. Backbone源码分析(一)

    距离上一篇博客有一段时间了,期间各种琐事萦绕.最主要的一件是,当我差不多将整个dojo核心源码看完,惊讶的发现dojo1.*的设计以是老态龙钟之象,而我沉溺在dojo中太久,已经不知道前端世界变成了什 ...

  3. [Voice communications] 看得到的音频流

    上文介绍了 Web Audio API 的相关知识,以及如何在你的 web 程序中引入 音频流,内容都是介绍性的,所以没有写太多 DEMO.本文重点讲解如何利用 Web Audio API 中的中间节 ...

  4. 日志系统实战(三)-分布式跟踪的Net实现

    介绍 在大型系统开发调试中,跨系统之间联调开始变得不好使了.莫名其妙一个错误爆出来了,日志虽然有记录,但到底是哪里出问题了呢? 是Ios端参数传的不对?还是A系统或B系统提供的接口导致?相信有不少人遇 ...

  5. 企业IT管理员IE11升级指南【2】—— Internet Explorer 11 对Adobe Flash的支持

    企业IT管理员IE11升级指南 系列: [1]—— Internet Explorer 11增强保护模式 (EPM) 介绍 [2]—— Internet Explorer 11 对Adobe Flas ...

  6. Webstorm 10 for mac osx 注册机,序列号,kegen

    小菜最近get到mac体验机会,早就耳闻mac非常适合做开发,于是迫不及待的安装各种开发工具,不知不觉,轮到前端开发神器webstorm了,看了一下官网的价格,心拔凉拔凉的. 果断搜索注册机,搜到的结 ...

  7. Worktile协同特色之一:无处不在的关注

    团队沟通中常见问题 在回答这个问题之前,我们不妨先来思考一下,团队成员之间互相配合沟通的几个问题:1. 任务的执行者在完成这个任务时,如何通知到此任务相关联的其他成员,比如该任务的后续任务执行者?2. ...

  8. Hadoop 裡的 fsck 指令

    Hadoop 裡的 fsck 指令,可檢查 HDFS 裡的檔案 (file),是否有 corrupt (毀損) 或資料遺失,並產生 HDFS 檔案系統的整體健康報告.報告內容,包括:Total blo ...

  9. PHPCMS后台密码忘记解决办法

    什么是PHPCMS? PHPCMS是一款网站管理软件.该软件采用模块化开发,支持多种分类方式,使用它可方便实现个性化网站的设计.开发与维护.它支持众多的程序组合,可轻松实现网站平台迁移,并可广泛满足各 ...

  10. Eclipse代码格式化规范

    附件()是Eclipse代码格式文件,根据以下步骤导入到Eclipse中,帮助规范代码格式. 导入步骤:1. Window -> Performances2. Java -> Code S ...