动态语言运行时(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平台中引入了"逻辑即数据"的概念.也就是说,我们可以在代码里使用高级语言的形式编写一段逻辑, ...
随机推荐
- 基础概念(3):怎么写一个c程序?
总结卡片: 遵循c语言的规则,即可写出c程序.规则下有两个重要概念:函数与变量.就好像游戏中的打仗,要考虑怎么打,谁来打."怎么打"就是流程,把流程封装起来就是函数,流程也叫算法. ...
- gin源码解读2-揭开gin的神秘面纱
数据如何在gin中流转 func main() { gin.SetMode(gin.DebugMode) // 设置为开发模式 router := gin.Default() _ = router.S ...
- golang中的并发安全和锁
1. 并发安全 package main import ( "fmt" "sync" ) var ( sum int wg sync.WaitGroup ) f ...
- 【webpack4.0】---base.config.js基本配置(五)
一.创建项目初始化 1.初始化项目npm init -y 2.创建 src (用来存放开发环境的代码)文件夹. config (用来存放webpack的配置项)文件夹 3.安装webpack We ...
- 使用 electron 和 electron-forge 加载 本地磁盘资源 img 的问题
最近在学习使用 electron 进行桌面开发一款图片压缩的软件.遇到了加载本地磁盘文件的问题.记录一下其解决方案. 使用 electron 加载本地磁盘文件 第一种方法 设置webPreferenc ...
- Java 后台线程介绍
一 是啥? package com.aaa.threaddemo; /* * 一 Java后台线程? * 守护线程--也称"服务线程",他是后台线程, * 它有一个特性,即为用户 ...
- 社交网络分析的 R 基础:(二)变量与字符串
本章会从 R 语言中最基本的数据类型开始介绍,在此之后就可以开始 R 语言实践了.对社交网络分析而言,我们在处理字符串上所花费的时间要远远大于处理数字的时间,因此本章还会介绍常用的字符串处理操作. 变 ...
- 计算机网络再次整理————UDP例子[六]
前言 简单的说,UDP 没有 TCP 用的广泛,但是还有很多是基于UDP的程序的,故而简单介绍一下. 正文 秉承节约脑容量的问题,只做简单的介绍和例子,因为自己几乎也没怎么用过UDP. 只是了解和知晓 ...
- Sklearn 与 TensorFlow 机器学习实用指南第二版
零.前言 一.机器学习概览 二.一个完整的机器学习项目 三.分类 四.训练模型 五.支持向量机 六.决策树 七.集成学习和随机森林 八.降维 十.使用 Keras 搭建人工神经网络 十一.训练深度神经 ...
- PyTorch 介绍 | AUTOMATIC DIFFERENTIATION WITH TORCH.AUTOGRAD
训练神经网络时,最常用的算法就是反向传播.在该算法中,参数(模型权重)会根据损失函数关于对应参数的梯度进行调整. 为了计算这些梯度,PyTorch内置了名为 torch.autograd 的微分引擎. ...