.NET 4.0 常见问题解答 第 1 部分 -- DLR






4.77/5 (22投票s)
在本文中,我们将讨论新的 DLR 功能以及“dynamic”和“expando”对象。
IDynamicMetaObjectProvider 和 DynamicMetaObject 是什么?
引言
在本文中,我们将讨论 .NET framework 4.0 提供的新功能。然后我们将重点介绍 DLR 功能,并讨论“dynamic”和“expando”对象。我们还将创建一个自定义的“expando”类,并了解我们可以从中获得哪些好处。许多开发人员错误地认为“dynamic”对象是为了取代“reflection”和“object”类型而创建的,我们将努力消除这种误解。
抱歉重复发布。由于图片上传问题,我已删除旧文章并重新上传。
我从哪里获取 .Net 4.0?
您可以从 http://www.microsoft.com/downloads/details.aspx?FamilyID=ee2118cc-51cd-46ad-ab17-af6fff7538c9&displaylang=en 下载 .NET 4.0 beta
.NET 4.0 的重要新功能有哪些?
与其浏览 100 个新功能列表,不如让我们专注于我们认为最重要的 3 个功能。如果您有兴趣查看新功能的详细列表,请单击此处。
• Windows 工作流和 WCF 4.0:- 这是 4.0 中的一项重大更改。在 WCF 中,我们引入了简化的配置、发现、路由服务、REST 改进和工作流服务。在 WWF 中,我们对工作流的核心编程模型进行了更改。编程模型变得更加简单和健壮。最大的亮点是 WCF 和 WWF 之间的集成。
 
• 动态语言运行时:- DLR 为 .NET 4.0 CLR 添加了动态编程功能。随着 FAQ 的进展,我们将对此进行更多讨论。
• 并行扩展:- 这将有助于支持多核系统的并行计算。NET 4.0 在 LINQ 引擎中拥有 PLINQ 来支持并行执行。引入了 TPL(任务并行库),它通过常规方法调用和委托公开了并行构造,如并行“For”和“ForEach”循环。
我们将在接下来的几节中更详细地讨论上述功能。
.NET 4.0 最重要的新功能是什么?
WCF 和 WWF 的新功能是最有趣的功能之一。特别是 WWF 的新编程模型及其与 WCF 的集成将是值得关注的有趣之处。
DLR、并行编程和其他新功能似乎只是锦上添花,而不是引人注目的功能。Kathleen Dollard 在 http://msmvps.com/blogs/kathleen/archive/2009/01/07/the-most-important-feature-of-net-4-0.aspx 中对此进行了更详细的讨论
随着 FAQ 的继续,我们将看到更多这些功能。
.NET 4.0 框架中的 DLR 是什么?
DLR(动态语言运行时)是一组服务,可为 CLR 添加动态编程功能。DLR 使 LISP、Javascript、PHP、Ruby 等动态语言可以在 .NET 框架上运行。

有两种类型的语言:静态类型语言和动态类型语言。在静态类型语言中,您需要在设计时/编译时指定对象。动态类型语言可以在运行时识别对象。.NET DLR 帮助您在 CLR 之上托管用动态语言编写的代码。

由于 DLR 运行时,ruby、python、JavaScript 等动态语言可以无缝集成并在 CLR 中运行。因此,DLR 有助于为您喜欢的动态语言构建最佳体验。您的代码在与动态语言集成时会更加简洁和无缝。

 
与 DLR 的集成不仅限于动态语言。您还可以通过使用 COM 互操作绑定器更简洁地调用 MS Office 组件。
DLR 的重要优点之一是它为动态语言集成提供了一个中央统一的子系统。
你能详细介绍一下 DLR 子系统吗?
DLR 包含 3 个基本子系统:
• 表达式树:- 通过它,我们可以将语言语义表示为 AST(抽象语法树)的形式。DLR 使用 AST 动态生成代码,CLR 运行时可以执行该代码。表达式树是帮助 ruby、javascript 等各种动态语言与 CLR 一起运行的主要参与者。
• 调用站点缓存:- 当您对动态对象进行方法调用时,DLR 会缓存有关这些方法调用的信息。对于后续的方法调用,DLR 使用缓存历史信息进行快速分派。
• 动态对象互操作性 (DOI):- DOI 包含一组可用于创建动态对象的类。开发人员可以使用这些类来创建可在动态语言和静态语言中使用的类。
我们将在接下来的 FAQ 部分更详细地介绍上述所有功能。

我们如何使用动态语言的对象并将其类暴露给动态语言?
要使用 DLR 支持的动态语言中创建的类,我们可以使用“Dynamic”关键字。要将我们的类暴露给 DLR 感知的语言,我们可以使用“Expando”类。
因此,当您想使用在 Python、Ruby、Javascript、COM 语言等中创建的类时,我们需要使用动态对象来引用该对象。如果您希望您的类被动态语言使用,则需要通过继承“Expando”类来创建您的类。然后动态语言可以消费这些类。我们将在下一节介绍这两个类。

不要忘记下载库作者的帮助文档,了解如何使用 DLR 实现跨平台的动态语言 http://dlr.codeplex.com/Wiki/View.aspx?title=Docs%20and%20specs
我们可以看一个“Dynamic”对象的示例吗?
我们已经讨论过,“Dynamic”对象有助于无缝地使用 DLR 支持的动态语言中创建的对象。dynamic 关键字是动态对象互操作性子系统的一部分。
如果您将一个对象分配给一个动态类型变量(dynamic x=new SomeClass()),那么对“x”的所有方法调用、属性调用和运算符调用都将被延迟到运行时,并且编译器在编译时不会对“x”执行任何类型检查。
考虑下面的代码片段,我们尝试使用互操作服务对 Excel 应用程序进行方法调用。
// Get the running object of the excel application
object objApp = System.Runtime.InteropServices.Marshal.GetActiveObject("Excel.Application");
// Invoke the member dynamically
object x = objApp.GetType().InvokeMember("Name", System.Reflection.BindingFlags.GetProperty, null, objApp, null);
// Finally get the value by type casting
MessageBox.Show(x.ToString());
我们现在使用“dynamic”关键字编写相同的代码。
// Get the object using 
dynamic objApp1 = System.Runtime.InteropServices.Marshal.GetActiveObject("Excel.Application");
// Call the 
MessageBox.Show(objApp1.Name);
您可以清楚地注意到属性调用语法的简化。“invokemember”非常晦涩且容易出错。使用“dynamic”关键字,我们可以看到代码是如何简化的。

 
如果您尝试在 VS IDE 中查看属性,您会看到一条消息,说明您只能在运行时进行评估。

“Dynamic”、“Object”和反射之间有什么区别?
许多开发人员认为,“Dynamic”对象是为了取代“Reflection”或“Object”数据类型而引入的。 “Dynamic”对象的主要目标是无缝地在静态类型语言中使用动态语言创建的对象。但是,由于这个特性,它的一些目标与反射和对象数据类型重叠了。
最终,由于代码简化和缓存优势,它将取代反射和对象数据类型。动态对象的初始目标从未取代“reflection”或对象数据类型,但由于功能的重叠,它确实这样做了。
| 动态 | 对象/反射 | 
| 动态对象是 DLR 引擎提供的一个小功能,我们可以用它来调用动态语言创建的对象。其宏观图景是 DLR,它不仅有助于使用,还可以将您的类暴露给动态语言。 | 反射和对象类型仅用于引用在运行时不知道其函数和方法的类型。反射和对象类型无助于将您的类暴露给其他语言。它们纯粹用于使用其方法直到运行时的对象。 | 
| 语法代码相当简洁 | 语法有点学习曲线。 | 
| 由于方法调用缓存,性能得到提高。 | 目前不存在方法调用缓存。 | 
dynamic 关键字的优点和缺点是什么?
我们仍然记得我们是如何批评 VB6(好吧,我喜欢那门语言)的 variant 关键字,以及我们是如何赞赏 .NET 引入编译时检查功能的,那么为什么我们现在要改变呢。
好吧,糟糕的开发者会用最好的编程语言写出糟糕的代码,而好的开发者会用最差的编程语言腾飞。Dynamic 关键字是一个减少复杂性的好工具,如果使用不当,它就是一种诅咒。
因此,Dynamic 关键字的优点是:
• 帮助您在动态语言之间进行互操作。
• 消除糟糕的反射代码并简化代码复杂性。
• 通过方法调用缓存提高性能。
缺点:
• 如果与强类型类一起使用,会影响性能。
Expando 对象是什么?
‘Expando’对象服务于互操作性的另一端,即使您的自定义类能够被动态语言使用。因此,您可以创建一个“Expando”类的对象并将其传递给 ruby、javascript、python 等动态语言。“Expando”对象有助于动态添加属性。它是动态属性包的高效实现。为了使用“ExpandoObject”,我们首先需要导入“System.Dynamic”命名空间。
using System.Dynamic;
然后我们创建“ExpandoObject”的对象,并将其分配给一个由“Dynamic”类类型创建的对象。请注意,如果我们使用了“Dynamic”对象而不是 expand 对象,这是因为我们仍然不知道将在运行时创建哪些属性。
dynamic obj = new ExpandoObject();
要创建动态属性,我们只需编写属性名称并设置值。
obj.Customername = "Some Customer Name";
最后,我们显示值。
MessageBox.Show(obj.Customername);
我们可以实现自己的“Expando”对象吗?
“Expando”对象在内部就是将属性添加到集合中。因此,您可以创建自己的“Expando”对象版本。
我们需要做的第一件事是继承“DynamicObject”类。
public class clsMyExpando : DynamicObject
{
}
正如之前所说,我们需要定义一个集合来存储属性。第二步,我们创建了一个字典对象来维护集合中的属性。
public class clsMyExpando : DynamicObject
{
Dictionary<string,> items= new Dictionary<string,>();
}
</string,></string,>
我们现在可以使用“TryGetMember”和“SetGetMember”来定义我们的 get 和 set 属性。
public class clsMyExpando : DynamicObject
{
Dictionary<string,> items = new Dictionary<string,>();
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
return items.TryGetValue(binder.Name, out result);
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
items[binder.Name] = value;
return true;
}}
</string,></string,>
我们现在可以创建我们的自定义“expando”类的对象,并将其分配给动态类引用。在下面的代码片段中,我们分配了一个名为“Name”的动态属性。
dynamic obj = new clsMyExpando(); obj.Name = "Dynamic Property";
使用自定义“Expando”类的优点是什么?
自定义“Expando”对象可用于提高性能。如果您的类包含一些静态属性和一些动态属性,那么您可以直接在自定义 expand 类中创建静态属性,如以下代码所示。因此,当调用对象的静态属性时,它不会调用字典集合,从而提高性能。DLR 引擎首先尝试调用属性名,而不是调用“TryGetMember”或“TrySetMember”。
第一点是避免使用“expando”自定义类,除非您有动态属性需求并且想要与动态语言通信。如果您有动态属性需求,请确保您确定的属性已添加到类中,并且动态属性是通过继承 dynamicobject 类实现的。
public class clsMyExpando : DynamicObject
    {
Dictionary<string,> items
        = new Dictionary<string,>();
        
        private string _Name;
        public string Name
        {
            get
            {
                return _Name;
            }
            set
            {
                _Name = value;
            }
        }
        public override bool TryGetMember(
            GetMemberBinder binder, out object result)
        {
            return items.TryGetValue(binder.Name, out result);
        }
        public override bool TrySetMember(
            SetMemberBinder binder, object value)
        {
            items[binder.Name] = value;
            return true;
        }
    }
</string,></string,>
IDynamicMetaObjectProvider 和 DynamicMetaObject 是什么?
“Dynamic”对象实现了“IDynamicMetaObjectProvider”并返回“DynamicMetaObject”。这两个接口都是实现动态语言之间互操作性的核心类。那么我们什么时候应该使用它呢:
- 如果我们想为快速动态属性检索实现自定义逻辑,我们可以实现“IDynamicMetaObjectProvider”和“DynamicMetaObject”。例如,您可能希望提供一种快速算法来检索最常用的属性。因此,您可以使用“IDynamicMetaObjectProvider”插入算法。
我们可以看到反射和动态对象执行之间的性能差异吗?
即将推出……
谢谢,谢谢,非常感谢
http://tomlev2.wordpress.com/category/code-sample/ 提供了展示如何实现动态对象的示例代码。
http://dlr.codeplex.com/Wiki/View.aspx?title=Docs%20and%20specs :- DLR 项目的 Codeplex 链接。
http://msmvps.com/blogs/kathleen/archive/2009/01/07/the-most-important-feature-of-net-4-0.aspx :- 讨论了 .NET 4.0 最重要的功能
http://blogs.msdn.com/brada/archive/2008/10/29/net-framework-4-poster.aspx :- 一张很棒的 4.0 全面海报,请确保您已安装 Silverlight 插件以利用缩放功能。
http://www.hanselman.com/blog/C4AndTheDynamicKeywordWhirlwindTourAroundNET4AndVisualStudio2010Beta1.aspx :- Sir Hansel 谈论了 dynamic 关键字。
https://codeproject.org.cn/KB/cs/dynamicfun.aspx :- Dynamic 示例实现。
http://en.wikipedia.org/wiki/Dynamic_Language_Runtime :- DLR 的 Wiki 链接。
http://msdn.microsoft.com/en-us/library/dd233052(VS.100).aspx :- 4.0 和 VS 2010 的下载链接。
http://www.developerfusion.com/article/9576/the-future-of-net-languages/2/ :- 讨论了 4.0 的新语言功能,我在网上没见过比这更简单的了。
http://www.gotnet.biz/Blog/file.axd?file=2009%2F6%2FHow+I+Learned+to+Love+Metaprogramming+-+CodeStock+2009.pdf :- Kevin MVP 关于元编程的精彩 PDF。
.NET 4.0 新功能详细列表
感谢 http://blogs.msdn.com/brada/archive/2008/10/29/net-framework-4-poster.aspx 发布了 .NET 4.0 功能的详细海报。我们只是将图形图表转换成了 excel 表格。
| Web | |
| System.Web.UI.DataVisualization.Charting | |
| 注释 | |
| 轴 | |
| 图表 | |
| 图表区域 | |
| 数据点 | |
| 图例 | |
| 系列文章 | |
| System.Web.Mvc | |
| 操作结果 | |
| 控制器 (Controller) | |
| 控制器工厂 | |
| IView 引擎 | |
| 查看页面 | |
| Ajax | |
| Sys.Binding | |
| Sys.Observer | |
| Sys.Data.DataSource | |
| Sys.UI.DataView | |
| Sys.UI.Template | |
| Sys.UI.TemplateResult | |
| 客户端 | |
| System.Windows.Input | |
| 触摸点 | |
| 触摸点集合 | |
| 触摸点设备 | |
| System.Windows.Controls | |
| 日历 | |
| 数据网格 | |
| 日期选择器 | |
| Ribbon | |
| RibbonWindow | |
| System.Windows | |
| VisualState | |
| VisualStateGroup | |
| VisualStateManager | |
| 核心 | |
| System.Numerics | |
| 大整数 | |
| 复杂 | |
| System.IO.MemoryMappedFiles | |
| System.ComponentModel.Composition | |
| CompositionContainer | |
| ExportAttribute | |
| ImportAttribute | |
| System.Linq | |
| 并行可枚举 | |
| System.Xaml | |
| XamlReader | |
| XamlWriter | |
| XamlType | |
| XamlProperty | |
| System.Threading.Tasks | |
| System.Collections.Generics | |
| 已存储集合 | |
| System.Runtime.Interop.Services | |
| TypeIdentifierAttribute | |
| System.Collections.Concurrent | |
| System.Threading | |
| LazyInit | |
| 并行 | |
| SpinLock | |
| 沟通 | |
| System.ServiceModel.Channel | |
| CompensationFlowAttributes | |
| System.ServiceModel | |
| CorrelationOperationBehavior | |
| OperationContact | |
| Service | |
| 服务合同 | |
| System.ServiceModel.Discovery | |
| AnnouncementClient | |
| AnnouncementService | |
| DiscoveryClient | |
| ServiceDiscoveryBehavior | |
| 工作流 | |
| System.WorkFlowModel | |
| Activity | |
| WorkFlowElement | |
| System.WorkFlowModel.Activities | |
| CompensationScope | |
| DbQuery | |
| DbUpdate | |
| FlowChart | |
| Persist | |
| 序列 | |
| StateMachine | |
| System.WorkFlowModel.Tracking | |
| Tracking.Profile | |
| System.WorkFlowServiceModel | |
| WorkFlowServiceHost2 | |
| System.WorkFlowServiceModel.Activities | |
| ClientOperation | |
| ReceiveMessage | |
| SendMessage | |
| ServiceOperation | |
| System.WorkFlowServiceModel.Dispatcher | |
| WorkFlowInstanceContext | |
| System.WorkFlowModel.Activity.Rules | |
| RuleSet | |
| Data | |
| System.Data.Sevices | |
| IDataServiceConfigulation | |
| Isynchronization Provider | |
| System.Data.Common.CommandTrees | |
| DbExpressionBuilder | |
| System.Data.Common | |
| EntitySqlParser | |
.NET 3.5 常见问题解答
有关 WCF 文章,请单击此处
有关 WPF 文章,请单击此处
有关 WWF 文章,请单击此处
有关 SilverLight 文章,请单击此处
有关 LINQ 文章,请单击此处

