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. Spring之注入的几种方式

    普通注入 在配置文件里 <!-- 构造注入 --> <bean id="user1" class="entity.User"> < ...

  2. Eclipse上安装GIT插件EGit及使用

    一.Eclipse上安装GIT插件EGit Eclipse的版本eclipse-java-helios-SR2-win32.zip(在Eclipse3.3版本找不到对应的 EGit插件,无法安装) E ...

  3. 启动App的Intent

    类似桌面图标打开App的Intent 程序中需要一种通知,点击后的效果需要像点击桌面图标那样: 程序在前台就什么也不干. 程序在后台,就切换到前台. 程序未启动,就启动程序. 点击通知后,通知本身跳转 ...

  4. MVC学习二:基础语法

    目录 一:重载方法的调用 二:数据的传递 三:生成控件 四:显示加载视图 五:强类型视图 六:@Response.Write() 和 @Html.Raw()区别 七:视图中字符串的输入 八:模板页 一 ...

  5. 循序渐进做项目系列(3):迷你QQ篇(1)——实现客户端互相聊天

    <循序渐进做项目系列迷你QQ篇>将陆续介绍客户端聊天,文件传输,加好友,群聊,包括语音聊天,视频聊天,远程桌面等等需求如何实现,感兴趣的朋友可以持续关注.考虑到某些需求较为复杂,本系列采用 ...

  6. CoffeeScript实现Python装潢器

    在上篇Angular遇上CoffeeScript – NgComponent封装中,我们讲述了CoffeeScript这门小巧的语言,摒弃JavaScript中糟粕(“坑”)部分,并将JavaScri ...

  7. Emacs 配置文件

    以下是我整理的 emacs 配置文件,供刚开始玩 emacs 的同学参考.网上有人说:emacs 是神的编辑器,如果能够用到这样的编辑器,那这个人就是神了.从我个人的经验来看,emacs 是一把利器, ...

  8. 图解C#的值类型,引用类型,栈,堆,ref,out

    C# 的类型系统可分为两种类型,一是值类型,一是引用类型,这个每个C#程序员都了解.还有托管堆,栈,ref,out等等概念也是每个C#程序员都会接触到的概念,也是C#程序员面试经常考到的知识,随便搜搜 ...

  9. [SDK2.2]SQL Azure (13) Azure的两种关系型数据库服务:SQL Azure与SQL Server VM的不同

    <Windows Azure Platform 系列文章目录> 如果熟悉Windows Azure平台的用户不难发现,对于SQL Server数据库来说,微软提供了两种服务,分别是: -W ...

  10. eclipse启动时报告错误:Java was started but returned exit code=-805306369

    这两天也没改过eclipse和java的配置,但eclipse启动时报告错误:Java was started but returned exit code=-805306369 后来在eclipse ...