微软Roslyn与CodeDom


110

从昨天在InfoWorld上有关新的Microsoft Roslyn新闻稿中

这种“解构”的编译器最明显的优点是,它允许从.Net应用程序中调用整个编译执行过程。Hejlsberg演示了一个C#程序,该程序将一些代码片段作为字符串传递给C#编译器。编译器将生成的IL汇编代码作为对象返回,然后将其传递给公共语言运行时(CLR)以执行。瞧!借助Roslyn,C#获得了动态语言在运行时生成和调用代码的能力。

自.NET 4发行以来,我就能够做到这一点CSharpCodeProvider.CompileAssemblyFromSource,实际上我在前一阵子编写的ASP.Net项目中使用了它,它确实做到了这一点-允许用户在文本框中键入代码,选择程序集/命名空间进行引用,然后即时执行并显示该代码的输出,以在Windows Azure上进行实时环境代码测试。

CodeDom罗斯林的前驱者的一部分吗?罗斯林(Roslyn)的特殊好处是CodeDom什么?

Answers:


240

免责声明:我在Roslyn团队为Microsoft工作。

CodeDom是罗斯林(Roslyn)的前身,但关系不大。本质上,CodeDom是一种简单的(某种程度上)与语言无关的方式来生成代码,该方法已添加到.NET 1.0中以支持设计人员(例如WinForms)。因为CodeDom试图提供一种可以用C#,VB和其他语言生成代码的统一模型,所以它缺乏对它支持的任何语言的保真度(这就是为什么您不能使用CodeDom创建switch语句)。CSharpCodeProvider.CompileAssemblyFromSource只是执行csc.exe的包装。

罗斯林是完全不同的动物。它是使用托管代码从头开始重写C#和VB编译器的-C#中的C#和VB中的VB(今天提供的csc.exe和vbc.exe版本是用本机代码编写的)。在托管代码中构建它们的好处是,用户可以将实际的编译器作为.NET应用程序中的库进行引用(无需包装)。

在构建编译器管道的每个组件时,我们在上面公开了公共API:

  • 解析器->语法树API
  • 符号表/元数据导入->符号API
  • 活页夹->绑定和流分析API
  • IL发射器->发射API

Roslyn可以用作复杂的C#和VB源代码生成器,但这就是与CodeDom相似的地方。Roslyn编译器API可用于解析代码,执行语义分析,动态编译和评估代码等。

除了编译器之外,Roslyn团队还在公共编译器API的基础重建Visual Studio C#和VB IDE功能。因此,编译器API足够丰富,可以构建Visual Studio设计时工具,例如IntelliSense和Extract Method重构。同样,在编译器之上的层中,Roslyn提供用于更高级别的分析或数据转换的服务。例如,有些服务可使用C#和VB格式化规则来格式化代码,或者在解决方案中查找对特定符号的所有引用。

的确,Roslyn与CodeDom相比并不仅有一项特殊优势。在CodeDom满足非常特定的代码生成需求的地方,Roslyn通过提供一个框架允许您构建几乎可以想到的任何C#或VB语言工具来解决整个语言工具领域。


2
@Dustin:罗斯林会支持其他语言吗?例如JavaScript(.NET)?
Diego Barros

@Dustin:这对于构建可以增强我组织中代码质量的完整IDE体验是完美的,尽管我看不到完全取代手动代码审查,但是我看到质量有了相当大的提高。不久!
杰里克·林恩斯

如果有人已经创建了一个基于Roslyn的工具,将使用CodeDom的代码转换为使用Roslyn的SyntaxFactory的代码,那就太好了(部分原因是.Net Core具有Roslyn但没有CodeDom,而我正在使用围绕CodeDom构建的库) )
艾默尔(Emyr

43

CodeDom允许您进行编译-但它不能使您真正地获得有关代码本身的信息(除了编译器错误)。基本上,这是一个黑框,您在其中说“编译此”,并说“我成功”或“我失败了,这里有一些错误”。

Roslyn允许您即时检查和构建代码。其中包括诸如查看/检查一段源代码中的注释,有关完整结构的详细信息等内容。您可以遍历并获取传递给Roslyn的源代码的整个语法树,并进行详细分析或对其进行转换。

有了完整而丰富的语法信息,您将拥有大量的额外控制权和灵活性。例如,这就是示例的工作方式,该示例复制一段C#代码并将其粘贴为VB.NET代码。使用Roslyn,您不仅可以进行编译,还可以做更多的事情-您还可以清晰地操作代码本身。这将使许多工具的生成更加简单,因为诸如重构之类的事情可以非常简单地完成,因为该工具可以理解完整的语法,包括元信息(如注释),并且可以直接使用它。


12

我看到一个很大的区别:使用CodeDom,每次您编译一些C#或VB.NET时,它都会发生在进程外。CSC.exe或VBC.exe是幕后的真正工人。

如果要构建服务,就体系结构,可伸缩性,隔离性等(您提到了Azure)而言,这不是很好。

随着罗斯林的到来。

我想这就是他们称之为“编译器即服务”的原因之一。

另外,CodeDom是一个相对较差的API,缺少许多功能,并且并不是最新的,因为它主要是为支持Visual Studio UI设计器的自动代码生成而设计的。我认为Roslyn会做得更好,因为它是由编写编译器的人编写的。我希望这会有所作为。

PS:与CSC.exe和VBC.exe有一个显着区别:Roslyn似乎是纯.NET(并使用CCI)。


8

Roslyn可以对整个过程进行更精细的控制-例如,您可以分析字符串,甚至生成其他代码(在基于分析的编译过程中即时生成)等。

CodeDom是“仅使用编译器”,而Roslyn是“可完全访问(子)部分的服务即编译器” ...通过Roslyn,您处于“编译器内部”,并且可以从编译器的角度查看代码的外观让您以目前无法实现的方式进行更改。

例如,您可以使用Roslyn扩展C#,这非常方便,并且比AOP实现的当前状态要好得多。

有关当前Roslyn状态及其提供的不同级别的访问和控制的概述,请参见http://msdn.microsoft.com/zh-cn/hh500769

更新

Microsoft刚刚提供了具有附加功能和许多API更改/添加的新CTP。有关详细信息,请参见此处


1
实际上,您可以使用Roslyn扩展带有其他关键字的C#是不正确的。
达斯汀·坎贝尔

谢谢...已更正...虽然不在第一版中,但我很可能这是可能的...
Yahia

2
@DustinCampbell,如果您处理了伪关键字由于生成代码而导致的任何编译器错误,该怎么办?
罗德里克·查普曼,

3
您需要先进行重写,然后再将其传递给编译器。首先,使用您的特殊关键字解析代码。该代码将进行解析,除非解析器无法对其进行正反翻译,否则无效关键字将在结果树中显示为SkippedTokenTrivia。然后,检测跳过的关键字并用有效代码(例如AOP编织)重写树。最后,将新树传递给编译器。不过,这绝对是一个hack,不能保证它可以与Roslyn的未来版本一起使用。例如,在将来的发行版中,解析器可能不会为残破的代码生成相同的树。
达斯汀·坎贝尔,

@DustinCampbell:但是在罗斯林决赛中会不会有允许AOP编织的东西?我的Mono.Cecil INPC编织效果仍然不错,但是如果我能写的话public notifying string Name {get;set;},那就更好了
TDaver 2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.