动态语言运行时概述
动态语言运行时(DLR)是一个运行时环境,它将一组动态语言的服务添加到公共语言运行时(CLR)。 DLR 使开发动态语言更易于在 .NET 上运行,并向静态类型语言添加动态功能。
动态语言可以在运行时标识对象的类型,而在静态类型语言(如 C# 和 Visual Basic)中(使用 Option Explicit On
时),必须在设计时指定对象类型。 动态语言的示例包括 Lisp、Smalltalk、JavaScript、PHP、Ruby、Python、ColdFusion、Lua、Cobra 和 Groovy。
大多数动态语言为开发人员提供以下优势:
- 能使用快速反馈循环(REPL 或称读取-评估-打印循环)。 这样,可以输入多个语句并立即执行它们以查看结果。
- 支持自上而下开发,以及更传统的自下而上开发。 例如,使用自上而下的方法时,可以调用尚未实现的函数,然后在需要它们时添加基础实现。
- 更易于重构和代码修改,因为无需在整个代码中更改静态类型声明。
动态语言是出色的脚本语言。 客户可以使用新的命令和功能轻松扩展使用动态语言创建的应用程序。 动态语言还经常用于创建网站和测试工具、维护服务器场、开发各种实用工具和执行数据转换。
DLR 的目的是使动态语言系统能够在 .NET 上运行,并为他们提供 .NET 互操作性。 DLR 将动态对象添加到 C# 和 Visual Basic 以支持这些语言中的动态行为,并启用它们与动态语言的互操作。
DLR 还有助于创建支持动态操作的库。 例如,如果你有使用 XML 或 JavaScript 对象表示法 (JSON) 对象的库,则对象可以显示为使用 DLR 的语言的动态对象。 这样,库用户就可以编写语法更简单、更自然的代码来使用对象和访问对象成员。
例如,可以使用以下 C# 代码在 XML 中增加一个计数器。
Scriptobj.SetProperty("Count", ((int)GetProperty("Count")) + 1);
通过使用 DLR,可以改用以下代码执行相同的操作。
scriptobj.Count += 1;
与 CLR 一样,DLR 是 .NET 的一部分。 可在 GitHub 上的 IronLanguages/dlr 存储库上下载它。
IronPython 是使用 DLR 开发的语言示例。
DLR 的主要优点
DLR 具有以下优势。
简化动态语言到 .NET 的移植
DLR 允许语言实现者避免创建词法分析器、分析器、语义分析器、代码生成器和其他传统上必须自行创建的工具。 若要使用 DLR,语言需要生成 表达式树,它们以树形结构表示语言级代码,运行时帮助程序例程,以及实现 IDynamicMetaObjectProvider 接口的可选动态对象。 DLR 和 .NET 自动执行大量代码分析和代码生成任务。 这使语言实现者能够专注于独特的语言功能。
在静态类型语言中实现动态功能
现有的 .NET 语言(如 C# 和 Visual Basic)可以创建动态对象,并将其与静态类型化对象一起使用。 例如,C# 和 Visual Basic 可以将动态对象用于 HTML、文档对象模型(DOM)和反射。
提供 DLR 和 .NET 的未来优势
使用 DLR 实现的语言可以受益于未来的 DLR 和 .NET 改进。 例如,如果 .NET 发布了具有改进的垃圾回收器或更快的程序集加载时间的新版本,则使用 DLR 实现的语言将立即获得相同的好处。 如果 DLR 添加了优化(例如更好的编译),则使用 DLR 实现的所有语言的性能也会提高。
允许共享库和对象
以一种语言实现的对象和库可由其他语言使用。 DLR 还支持静态类型语言和动态语言之间的互操作。 例如,C# 可以声明使用以动态语言编写的库的动态对象。 同时,动态语言可以使用 .NET Framework 中的库。
可以快速动态调度和调用
DLR 通过支持高级多态缓存来快速执行动态操作。 DLR 为绑定操作创建规则,这些操作将对象绑定到必要的运行时实现,然后缓存这些规则,以避免在同一类型的对象上连续执行相同代码时,进行消耗资源的绑定计算。
DLR 体系结构
DLR 将一组服务添加到 CLR,以便更好地支持动态语言。 这些服务包括:
表达式树。 DLR 使用表达式树来表示语言语义。 为此,DLR 扩展了 LINQ 表达式树,以包括控制流、分配和其他语言建模节点。 有关详细信息,请参阅 表达式树(C#) 或 表达式树(Visual Basic)。
调用站点缓存。 动态调用站点 是代码中的一个位置,可在其中对动态对象执行
a + b
或a.b()
等操作。 DLR 缓存a
和b
的特征(通常是这些对象的类型)以及有关操作的信息。 如果以前已执行此类操作,DLR 将从缓存中检索所有必要的信息,以便快速调度。动态对象互操作性。 DLR 提供一组表示动态对象和操作的类和接口,可由动态库的语言实现者和作者使用。 这些类和接口包括 IDynamicMetaObjectProvider、DynamicMetaObject、DynamicObject和 ExpandoObject。
DLR 在调用站点中使用绑定器,不仅与 .NET 通信,还与 COM 等其他基础结构和服务通信。 绑定器封装语言的语义,并指定如何使用表达式树在调用站点中执行操作。 这样使用 DLR 的动态和静态类型语言便可共享库,并访问 DLR 支持的所有技术。
DLR 文档
有关如何使用 DLR 的开放源代码版本向语言添加动态行为,或有关如何在 .NET 中使用动态语言的详细信息,请参阅 GitHub 上的 IronLanguages/dlr 存储库的文档。