现在的位置: 首页 > 综合 > 正文

基于Visual Studio2010与C#4.0新功能和展望–dynamic:用DynamicObject创建包装器

2012年09月19日 ⁄ 综合 ⁄ 共 4017字 ⁄ 字号 评论关闭

在以前的帖子我展示了如何在运行时使用新的dynamic功能和ExpandoObject类来添加和删除属性,这可以使你的代码比使用LINQ代码写入XML语法更具可读性和灵活性。
但也有一些明显的缺陷在例子中:虽然ExpandoObject提供更好的语法,LINQ to XML的图书馆提供了有益的方法,帮助您使用XML文件很多。因此,有可能是这两个优势结合起来,有更好的语法,仍然可以得到所有这些方法?答案是肯定的,但是你需要另一种类型的System.Dynamic命名空间:DynamicObject。
该DynamicObject类使您可以获取或设置覆盖像一个成员操作,调用一个方法,或执行任何二进制,一元,或类型转换操作。为了说明问题,让我们创建一个非常简单的对象覆盖了“获取属性”操作,所以,每当你进入一个属性返回一个字符串属性的名称。这个例子没有任何实际价值。

正如ExpandoObject,我们必须使用动态关键字来创建这个类的实例。

  

让我们看看会发生什么在这个例子上。当您调用obj.SampleProperty,动态语言运行时(DLR)使用的语言粘结剂寻找这一类属性在SampleObject静态定义。如果没有这样的属性,调用TryGetMember DLR的方法。这种方法得到的信息是什么财产要求通过粘结剂参数。正如你所看到的,binder.Name包含属性的实际名称。
该TryGetMember方法返回true,如果操作成功。但是,实际经营结果必须被分配到out参数的结果。在这个例子中,TryGetMember返回true,但obj.SampleProperty返回“SampleProperty”。
现在让我们转向更为复杂的例子,并创造一个XElement对象包装。再次,我会尽量提供下列LINQ到XML示例更好的语法。

首先,我要创造一个ExpandoObject模拟。我仍然希望能够动态地添加和删除属性。但由于我基本上是创造一个有利于XElement类型的包装,我将使用XElement而不是字典保持性能。

这里是你如何可以使用这个类。

让我们看看在接触对象。当这个对象被创建时,它会初始化内部的XElement。如果您设置一个属性值,在contact.Phone =“206-555-0144喜欢”,该TrySetMember方法检查是否具有名称电话元素在其XElement存在。如果它不存在,该方法创建的元素。
下一个有趣的路线是contact.Address =新DynamicXMLNode()。基本上,在这个特殊的例子,我此行就是要创建一个节点有子节点。对于此属性,TrySetMember方法创建一个XElement没有值。
最复杂的案件在这里是一个如contact.Address.State行=“娃”。首先,TryGetMember方法要求contact.Address并返回一个新的DynamicXMLNode对象,它是由具有名称地址XElement初始化。 (理论上,我可以回到自己的XElement,但是这将让这个例子更加复杂化。)然后TrySetMember方法被调用。该方法查找在contact.Address国的因素。如果它没有找到一个,它创建它。
因此,我已成功地创建了所需的XML结构。但TryGetMember总是返回一个DynamicXMLNode实例。我如何获取XML节点的实际价值?举例来说,我希望下面的行工作,但现在它抛出一个异常。
弦乐状态= contact.Address.State,我这里有几种选择。我可以修改TryGetMember方法返回实际值的叶节点,例如。但是,让我们探讨一个选项:覆盖类型转换。只需将以下方法添加到DynamicXMLNode类。

现在,每当我有一个明确的DynamicXMLNode式或隐式类型转换,TryConvert方法被调用。该方法检查的对象是什么类型转换为,如果该类型是String,该方法返回的内部XElement价值。否则,它返回false,这意味着该语言应确定下一步该怎么做在大多数情况下(这意味着你将得到一个运行时异常)。
最后一点我要说明的是如何让访问XElement方法。让我们重写TryInvokeMember方法,以便将重定向所有方法调用它的XElement对象。当然,我这里使用System.Reflection命名空间。

此方法使您能够调用任何DynamicXMLNode对象的节点XElement方法。最明显的缺点,这里是智能感知的情况下。
我什至会假装,这个例子是对LINQ的准备使用的包装,以XML库。它不支持属性,不允许你创建一个节点集合(例如,多个联系人),它可能是失踪的其他功能。创建一个库是一项艰巨的任务,并创造一个良好的包装太。但我希望在阅读这个博客帖子你可以自己创建一个DynamicObject充分运作的包装。
所以,如果你经常使用复杂的语法与检索的XML脚本文件或对象,或者如果您是自己建立这样一个库工程库,你应该考虑写一个包装。这样做可能让你更有效率和您的图书馆语法好得多。

 

 以上程序都在Visual Studio 2010 Beta 2中调试通过。

抱歉!评论已关闭.