动态语言运行时(DLR)
前言
为了让C#、Visual Basic等.NET编程语言能具备动态编程语言的特性,.NET 4.0引入了一个“DLR(Dynamic Language Runtime:动态语言运行时)”(图 3)。

DLR运行于CLR之上,提供了一个动态语言的运行环境,从而允许Python、Ruby等动态语言编写的程序在.NET平台上运行,同时,现有的.NET静态类型编程语言,比如C#和Visual Basic,也可以利用DLR而拥有一些动态编程语言的特性。
为什么动态代码第一次慢,后面就解决静态语言了
由于DLR自身设计了一个“规则”缓存系统(DLR设计了一个三级缓存策略),又充分利用了CLR所提供的JIT缓存(因为所有动态调用代码最终都会转换为CLR可以执行的IL指令,而CLR可以缓存这些代码),使得动态代码仅仅在第一次执行时性能较差,后续的连续调用其性能可以逼近静态代码。
(1)使用C# 4编写动态的代码
C# 4新增了一个dynamic关键字,可以用它来编写“动态”的代码。
例如,以下代码创建了一个ExpandoObject对象(注意必须定义为dynamic):
dynamic dynamicObj = new ExpandoObject();
这一对象的奇特之处在于,我们可以随时给它增加新成员:
dynamicObj.Value = 100; //添加字段
dynamicObj.Increment = new Action(() => dynamicObj.Value++); //添加方法
这些动态添加的成员与普通的类成员用法一样:
for (int i = 0; i < 10; i++)
dynamicObj.Increment();//调用方法
Console.WriteLine("dynamicObj.Value={0}",dynamicObj.Value);//访问字段
ExpandoObject对象实现了IDictionary<string, object>接口,可看成是一个字典对象,所有动态添加的成员都是这个字典对象中的元素,这意味我们不仅可以添加新成员,还可以随时移除不再需要的成员:
//移除Increment方法
(dynamicObj as IDictionary<string, object>).Remove("Increment");
方法移除之后,再尝试访问此方法将引发RuntimeBinderException异常。
表达式树和动态语言运行时(DLR)是什么关系
动态语言运行时(DLR)
动态语言运行时(Dynamic Language Runtime, DLR)是处理动态对象的一种便捷方法。比如,假设您有 XML 或 JSON 格式的数据,其中的成员事先并不知道。DLR 允许您使用自然代码来处理对象和访问成员。
对于 C#,这使您可以处理在编译时不知道其类型的库。动态类型消除了自然 API 代码中的万能字符串。这就开启了像 IronPython 一样位于 CLR 之上的动态语言。
DLR 向 CLR 添加了一组服务,以便更好地支持动态语言。 这些服务包括:
- 表达式树。 DLR 使用表达式树来表示语言语义。 为此,DLR 扩展了 LINQ 表达式树,使其包含控制流、分配和其他语言建模节点。 有关详细信息,请参阅表达式树 (C#) 或表达式树 (Visual Basic)。
- 调用点缓存。 动态调用点是代码中对动态对象执行
a + b或a.b()等操作的位置 。 DLR 会缓存a和b(通常为这些对象的类型)的特征,以及有关操作的信息。 如果之前已经执行过此类操作,则 DLR 会从缓存中检索所有的必要信息,以实现快速调度。 - 动态对象互操作性。 DLR 提供一组表示动态对象和操作的类和接口,供语言实现者和动态库的作者使用。 这些类和接口包括IDynamicMetaObjectProvider、DynamicMetaObject、DynamicObject 和 ExpandoObject。
要了解 DLR 和 CLR 是如何结合在一起的,请看下图:

DLR 支持高级多态缓存,因此可以快速执行动态操作。
总结
即我们所知道的调用点缓存来避免每次动态代码被调用时的重新编译。动态分配确保适当的语言结合(Language Binders)能够用于动态调用。
C# 动态类型或许看起来令人望而生畏,但它在强类型系统之上有很多好处。DLR 是所有动态操作发生和与 CLR 交互的地方,类型继承使同时处理这两个类型系统变得容易。在 C# 中,动态和静态编程之间并没有对立,这两种类型系统共同协作,以创造性的方式解决动态问题。
https://ittranslator.cn/dotnet/csharp/2021/01/20/working-with-the-dynamic-type-in-csharp.html
https://docs.microsoft.com/zh-cn/dotnet/framework/reflection-and-codedom/dynamic-language-runtime-overview

动态语言运行时(DLR)的更多相关文章
- 关于使用动态语言运行时 (. net)
AutoCAD Managed .NET API允许您使用使用. NET 4.0 引入的动态语言运行时 (DLR). 使用DLR可以直接访问对象, 而无需: 打开一个对象进行读取或写入, 然后在完成后 ...
- 《精通C#》第十六章-动态类型和动态语言运行时-第一节至第四节
在.Net4.0中引入了一个关键字dynamic,这是一个动态类型关键字.Net中还有一个关键字是var,这是一个隐式类型,可以定义本地变量,此时var所代表的实际的数据类型有编译器在初次分配时决定, ...
- 日志系统实战(二)-AOP动态获取运行时数据
介绍 这篇距上一篇已经拖3个月之久了,批评自己下. 通过上篇介绍了解如何利用mono反射代码,可以拿出编译好的静态数据.例如方法参数信息之类的. 但实际情况是往往需要的是运行时的数据,就是用户输入等外 ...
- C语言运行时数据结构
段(Segment): 对象文件/可执行文件: SVr4 UNIX上被称为ELF(起初"Extensible Linker Format", 现在"Executable ...
- 使用Mono Cecil 动态获取运行时数据 (Atribute形式 进行注入 用于写Log) [此文报考 xxx is declared in another module and needs to be imported的解决方法]-摘自网络
目录 一:普通写法 二:注入定义 三:Weave函数 四:参数构造 五:业务编写 六:注入调用 7. 怎么调用别的程序集的方法示例 8. [is declared in another module ...
- 动态链接--运行时加载dlopen
前面我们在编译可执行文件时,如果可执行文件要依赖某个so.必须要通过-L指定so路径,并且-l指定so名字. 而且在可执行文件运行时,要先加载so的load部分到进程地址空间. 有一种方式可以在编译时 ...
- 在使用Qt5.8完成程序动态语言切换时遇到的问题
因为之前了解过一些Qt国际化的东西,所以在写程序的时候需要显示给用户的字符都使用了 tr(" ")的形式,然后使用 Qt Linguist得到相应的 qm(Qt message)文 ...
- 类CL_ABAP_TYPEDESCR,动态取得运行时类型
有时候我们要在程序运行的时候取得某个内表或者某个结构它的属性或者它的字段的属性,可能通过类CL_ABAP_TYPEDESCR和它的子类取得指定内表的属性.类CL_ABAP_TYPEDESCR和它的子类 ...
- 【C#表达式树 开篇】 Expression Tree - 动态语言
.NET 3.5中新增的表达式树(Expression Tree)特性,第一次在.NET平台中引入了"逻辑即数据"的概念.也就是说,我们可以在代码里使用高级语言的形式编写一段逻辑, ...
随机推荐
- Ajax_axios发送ajax请求
Ajax_axios发送ajax请求 这篇笔记主要讲一下axios基本的发送ajax请求的方法 axios在当前的前端行业里面是用的比较热门的一个 下面给大家分享一下它axios的一个基本用法 这段代 ...
- HBase结构
Pig,可以使用Pig Latin流式编程语言来操作HBase中的数据 Hive,可以使用类似SQL语言来访问HBase,最终本质是编译成MapReduce Job来处理HBase表数据,适合做数 ...
- gin中的文件上传
1. 单文件上传 package main import ( "fmt" "github.com/gin-gonic/gin" "log" ...
- python 爬虫爬取历年双色球开奖信息
目前写的这些爬虫都是些静态网页,对于一些高级网页(像经过JS渲染过的页面),目前技术并不能解决,自己也是在慢慢学习过程中,如有错误,欢迎指正: 对面前端知识本人并不懂,过程中如果涉及到前端知识,也是百 ...
- yum源 epel源 no package available 更换国内yum源
有时候安装软件会出现 no package available 解决办法:yum install epel-release 安装完会在/etc/yum.repos.d/目录下下生成两个repo文件: ...
- 用8个命令调试Kubernetes集群
如果使用任何系统的时间足够长,那么你肯定必须对其进行调试,Kubernetes也不例外.它是一个分布式系统,有许多运动部件.我们将介绍8个可以运行以调试任何Kubernetes集群的命令. 它将帮助你 ...
- 回顾 2021 中国 .NET 开发者峰会
.NET Conf China 2021 是面向开发人员的社区峰会,基于 .NET Conf 2021,庆祝 .NET 6 的发布和回顾过去一年来 .NET 在中国的发展.峰会由来自北京.上海.苏州. ...
- 论新手该如何学习java?
由于我国高等教育制度教材陈旧,加上java自身发展不过十年左右的时间,还有一个很重要的原因就是java这门语言更适合商业应用,所以高校里大部分博士老师们对此语言的了解甚至不比本科生多. 在这种环境下, ...
- 分布式缓存系统——memcache
一.简介 memcache是一个自由开源的.高性能的.分布式内存对象缓存系统.它是一种基于内存的key-value存储,用来存储小块的任意数据(字符串.对象).这些数据可以是数据库调用.API调用等. ...
- 微信公众号之微信登录失败,redirect_uri域名与后台配置不一致,错误代码10003
前几次也遇到过这个问题:没有注意,今天记一下 解决:把你出错页面的url复制出来,看下域名是多少,然后在相应的微信公众号位置加上该域名即可 第一步:登录微信公众号: 第二步:将文件下载后,利用工具传入 ...