微软 Roslyn vs CodeDom

昨天在 InfoWorld 的一个 新闻稿节目中谈到了新的 微软 Roslyn:

这种“解构”编译器最明显的优点是 它允许从中调用整个编译-执行过程 Hejlsberg 演示了一个 C # 程序 将一些代码片段作为字符串传递给 C # 编译器; 编译器 将结果 IL 汇编代码作为对象返回,然后 交由通用语言运行库执行 C # 获得了动态语言生成和调用的能力 运行时代码。

我能做到这一点,自从发布。NET 4和 CSharpCodeProvider.CompileAssemblyFromSource,我实际上在不久前编写的一个 ASP.NET 项目中使用了它,它完全做到了这一点——允许用户在文本框中输入代码,选择要引用的程序集/名称空间,然后执行并显示来自该代码的输出,以便在 Windows Azure 上进行实时环境代码测试。

CodeDom是罗斯林的前身吗? 罗斯林相对于 CodeDom有什么特别的好处?

34811 次浏览

CodeDom allows you to compile - but it doesn't give you the ability to really get information about the code itself (other than compiler errors). Basically, it's a black box where you say "compile this" and it says "I succeeded" or "I failed, here are some errors".

Roslyn 允许您在运行时完全检查和构建代码。这包括能够查看/检查源代码中的注释、关于完整结构的详细信息等。您可以遍历并获取传递到罗斯林的源代码的整个语法树,并对其进行详细的分析或转换。

给定完整、丰富的语法信息,您将获得大量额外的控制和灵活性。例如,示例就是这样工作的,它复制一个 C # 代码块并将其粘贴为 VB.NET 代码。使用 Roslyn,您可以做的不仅仅是编译——您还可以干净利落地操作代码本身。这将使得许多工具的生成更加简单,因为像重构这样的事情可以非常简单地完成,因为工具理解完整的语法,包括元信息(比如注释) ,并且可以直接使用它。

Roslyn 允许对整个过程进行更精细的控制——例如,您可以分析字符串,甚至生成额外的代码(基于分析的编译过程中的动态代码) ,等等。

CodeDom 是“仅仅使用编译器”,而 Roslyn 是“编译器作为一种服务,可以完全访问(子)部分”... ... 在 Roslyn 中,你是“在编译器内部”,可以从编译器的角度看到代码的样子,允许你以目前不可能的方式进行更改。

For example, you can use Roslyn to extend C# - something very handy and much better than the current state of AOP implementation.

有关目前罗斯林的概况及其提供的不同级别的访问和控制,请参阅 ABc0

更新

微软刚刚发布了一个新的 CTP,其中包含了更多的特性和大量的 API 更改/添加。

One big difference I see: with CodeDom, each time you compile some C# or VB.NET, it happens out of process. CSC.exe or VBC.exe are the real workers behind the scene.

如果你想构建一个服务,在架构、可伸缩性、隔离性等方面(你提到了 Azure) ,这是不太好的。

罗斯林那边正在进行。

I suppose this is one of the reason they call it "Compiler as a service".

此外,CodeDom 是一个相对较差的 API,缺少很多特性,并且不是真正最新的,因为它的设计主要是为了支持 Visual Studio UI 设计人员自动生成代码。我认为 Roslyn 会做得更好,因为它是由编译器的人编写的。我希望这会有所帮助。

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

免责声明 : 我在微软的罗斯林团队工作。

CodeDom 是罗斯林的前身,但只是略微相关。从本质上讲,CodeDom 是一种简单的(在某种程度上)语言无关的方法,用于生成添加到。NET 1.0支持设计器(如 WinForms)。因为 CodeDom 试图提供一个统一的模型,可以用 C # 、 VB 和其他语言生成代码,所以它对它支持的任何语言都缺乏高保真度(这就是为什么你不能用 CodeDom 创建 switch 语句的原因)。CSharpCodeProvider.CompileAssemblyFromSource 只是执行 csc.exe 的包装器。

Roslyn 是完全不同的动物。它使用托管代码(C # 中的 C # 和 VB 中的 VB)从头开始重写 C # 和 VB 编译器(目前发布的 csc.exe 和 vbc.exe 版本都是用本机代码编写的)。在托管代码中构建编译器的优点是,用户可以从。NET 应用程序(不需要包装器)。

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

  • 解析器-> 语法树 API
  • 符号表/元数据导入-> 符号 API
  • Binder -> Binding and Flow Analysis APIs
  • IL 发射器-> 发射 API

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

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

事实上,罗斯林的特殊优势并不仅仅局限于 abc 0而非 codeDom。在 CodeDom 满足了特定代码生成需求的地方,Roslyn 提供了一个框架,允许您构建任何类型的 C # 或 VB 语言工具,从而解决了整个语言工具空间的问题。

截至2022年1月10日,罗斯林的使用有一个相当严重的内存泄漏,使它几乎不可用报告在这里和一个独立的,但可能有关的问题,离开文件句柄打开报告在这里。这两个问题已经公开了近两年。

因此,目前 CodeDom 和罗斯林之间的一个很大的区别是,由于存在这些问题,Roslyn 无法在多次调用编译代码的生产环境中使用。CodeDom 不会遇到这些问题。

我只是觉得,对于那些正在考虑重写现有代码的人来说,了解这些信息非常重要。