本文转载:http://joe-bq-wang.iteye.com/blog/1872756

里面有动态Linq to xml的写法。

There is a expando object which allow you add/remove properties at runtime, DynamicObject provides ou with more capability and it is better used in places where a wrapper excels a raw XML file or script object syntax.

First, we will intoduce the  DynamicObject, as stated in the References Section on "DynamicObject Class",which defines some methods such as TryGetMember, TrySetMember, TryInvokeMembers which acts as a proxy to the real value contained in the DynamicObject derived classes. Also, DynamicObject has special support from the DLR (Dynamic Language Runtime) which means it has some special translation when you use DynamicObject with "dynamic" keyword.

First, we will see a example object with DynamicObject which has the ability to let you query/set values in case-insensitive fashion, which the real data is backed by a Dictionary.

  1. using System.Collections.Generic;
  2. using System.Dynamic;
  3. namespace DynamicObjectDemo
  4. {
  5. class DynamicDictionary : DynamicObject
  6. {
  7. private Dictionary<string, object> dictionary = new Dictionary<string, object>();
  8. public int Count
  9. {
  10. get { return dictionary.Count; }
  11. }
  12. public override bool TryGetMember(GetMemberBinder binder, out object result)
  13. {
  14. string name = binder.Name.ToLower();
  15. return dictionary.TryGetValue(name, out result);
  16. }
  17. public override bool TrySetMember(SetMemberBinder binder, object value)
  18. {
  19. dictionary[binder.Name.ToLower()] = value;
  20. return true;
  21. }
  22. }
  23. }

and here is a test program to show you how to use the DynamicDictionary class.

  1. namespace DynamicObjectDemo
  2. {
  3. /// <summary>
  4. /// Main method to test the DynamicObject
  5. /// </summary>
  6. /// <remarks>
  7. /// <para>
  8. /// Please find references information from: http://msdn.microsoft.com/en-us/library/system.dynamic.dynamicobject.aspx
  9. /// </para>
  10. /// </remarks>
  11. class Program
  12. {
  13. static void Main(string[] args)
  14. {
  15. // you must use the "Dynamic" keyword to create object, otherwise, you won't be able to use get the dynamic behavior
  16. dynamic person = new DynamicDictionary();
  17. // adding new Dictionary Properties
  18. person.FirstName = "Ellen";  //  the dynamic language runtime (DLR) first uses the language binder to look for a static definition of a property in the class. If there is no such property, the DLR calls the TrySetMember method.
  19. person.LastName = "Adams";
  20. //getting values of the dynamic properties
  21. // the tryGetMember methods is called
  22. Console.WriteLine(person.FirstName + " " + person.lastname); // this time, we uses the lower case member
  23. Console.WriteLine("NUmber of dynamic properties" + person.Count);
  24. try
  25. {
  26. // the following will throw Exception at runtime,
  27. // when the TryGetMember method return a false, and this causes a
  28. // RuntimeBinderException
  29. Console.WriteLine(person.address);
  30. }
  31. catch (RuntimeBinderException ex)
  32. {
  33. Debug.WriteLine("caught exception calling person.address: {0}", ex.ToString());
  34. }
  35. catch (Exception ex)
  36. {
  37. Debug.WriteLine("Some unknown exception : {0}", ex.ToString());
  38. }
  39. }
  40. }
  41. }

With DynamicObject, you can do even more, suppose that we have an XElement and we know we can create an XElement with some syntax as below.

  1. XElement contactXML =
  2. new XElement("Contact",
  3. new XElement("Name", "Patrick Hines"),
  4. new XElement("Phone", "206-555-0144"),
  5. new XElement("Address",
  6. new XElement("Street1", "123 Main St"),
  7. new XElement("City", "Mercer Island"),
  8. new XElement("State", "WA"),
  9. new XElement("Postal", "68042")
  10. )
  11. );

however, we can make it even simpler. what we have in mind is something like this:

  1. dynamic contact = new DynamicXMLNode("Contacts");
  2. contact.Name = "Patrick Hines";
  3. contact.Phone = "206-555-0144";
  4. contact.Address = new DynamicXMLNode();
  5. contact.Address.Street = "123 Main St";
  6. contact.Address.City = "Mercer Island";
  7. contact.Address.State = "WA";
  8. contact.Address.Postal = "68402";

we might need to write Dyanmic Extended class  with the following override.s

TryGetMember : the Contact.Address.Street part in the Contact.Address.Street statement (the part to get some member back)

TrySetMember: contact.Name = "Patrick Hines";

TryConvert: contact.Name = "Patrick Hines"; (Expected value type is String, but returned type is a DynamicXMLNode)

TryInvokeMember: we have hide the XElement , this enables us to the hidden methods supported by the Xlement

here is the full code of the implementation of DynamicXMLNode.

  1. using System;
  2. using System.Dynamic;
  3. using System.Reflection;
  4. using System.Xml.Linq;
  5. namespace DynamicObjectDemo
  6. {
  7. /// <summary>
  8. /// A wrapper on the XElement
  9. /// </summary>
  10. /// <remarks>
  11. /// <para>
  12. /// You can find some reference page from
  13. ///     * Dynamic in C# 4.0: Creating Wrappers with DynamicObject:  http://blogs.msdn.com/b/csharpfaq/archive/2009/10/19/dynamic-in-c-4-0-creating-wrappers-with-dynamicobject.aspx
  14. /// </para>
  15. /// </remarks>
  16. public class DynamicXMLNode : DynamicObject
  17. {
  18. XElement node;
  19. public DynamicXMLNode(XElement node)
  20. {
  21. this.node = node;
  22. }
  23. public DynamicXMLNode()
  24. {
  25. }
  26. public DynamicXMLNode(string name)
  27. {
  28. node =new XElement(name);
  29. }
  30. public override bool TryGetMember(GetMemberBinder binder, out object result)
  31. {
  32. XElement getNode = node.Element(binder.Name);
  33. if (getNode != null)
  34. {
  35. result = new DynamicXMLNode(getNode);
  36. return true;
  37. }
  38. else
  39. {
  40. result = null;
  41. return false;
  42. }
  43. }
  44. public override bool TrySetMember(SetMemberBinder binder, object value)
  45. {
  46. XElement setNode = node.Element(binder.Name);
  47. if (setNode != null)
  48. {
  49. setNode.SetValue(binder.Name);
  50. }
  51. else
  52. {
  53. if (value.GetType() == typeof (DynamicXMLNode))
  54. {
  55. node.Add(new XElement(binder.Name));
  56. }
  57. else
  58. {
  59. node.Add(new XElement(binder.Name, value));
  60. }
  61. }
  62. return true;
  63. }
  64. // TryGetMember always returns an instance of DynamicXMLNode. How do I get the actual value of the XML node? For example, I want the following line to work, but now it throws an exception.
  65. //   String state = contact.Address.State
  66. // one option is to return the actual values for leaf nodes, but to explore another option: you can try the type conversion, just add the following method to the DynaxmicXMLNode class
  67. public override bool TryConvert(ConvertBinder binder, out object result)
  68. {
  69. if (binder.Type == typeof(string))
  70. {
  71. result = node.Value;
  72. return true;
  73. }
  74. else
  75. {
  76. result = null;
  77. return false;
  78. }
  79. }
  80. // though we can get manipulate indirectly to XElement values wrapped by the DynamicXMLNode, we can even get the contained result
  81. // out of the DynamicXMLNode, we cannot call methods which is suppose to work on XElement, here is what in addition you can
  82. // to get Access to XElement methods
  83. public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
  84. {
  85. Type xmlType = typeof(XElement);
  86. try
  87. {
  88. result = xmlType.InvokeMember(binder.Name,
  89. BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Instance,
  90. null,
  91. node,
  92. args);
  93. return true;
  94. }
  95. catch
  96. {
  97. result = null;
  98. return false;
  99. }
  100. }
  101. }
  102. }

to give an impression on the capability that the DynamixXMLNode has empowered us, let 'see the test code below.

  1. public class DynamicXMLNodeMain
  2. {
  3. public static void DynamicXMLNodeCreateReturnValidDynamixXMLNode()
  4. {
  5. dynamic contact = CreateDynamicXMLNode();
  6. if (contact != null)
  7. {
  8. Console.WriteLine("Created DynamicXMLNode ");
  9. }
  10. else
  11. {
  12. Console.WriteLine("Failed to create DynamicXMLNode");
  13. }
  14. }
  15. public  static void DynamicXMLNodeConvertToStringReturnXElementValue()
  16. {
  17. dynamic contact = CreateDynamicXMLNode();
  18. string state = contact.Address.State;
  19. Console.WriteLine("State is {0}", state);
  20. }
  21. public static void DynamicXMLNodeTryInvokeMemberCallXElementMethods()
  22. {
  23. dynamic contact = CreateDynamicXMLNode();
  24. contact.Address.Postal.SetValue("newPostValue");
  25. string newPostal = contact.Address.Postal;
  26. if (newPostal == "newPostValue")
  27. {
  28. Console.WriteLine("Set new Post value");
  29. }
  30. else
  31. {
  32. Console.WriteLine("Failed to set new postal value");
  33. }
  34. }
  35. public static DynamicXMLNode CreateDynamicXMLNode()
  36. {
  37. dynamic contact = new DynamicXMLNode("Contacts");
  38. contact.Name = "Patrick Hines";
  39. contact.Phone = "206-555-0144";
  40. contact.Address = new DynamicXMLNode();
  41. contact.Address.Street = "123 Main St.";
  42. contact.Address.City = "Mercer Island";
  43. contact.Address.State = "NA";
  44. contact.Address.Postal = "68402";
  45. return contact;
  46. }
  47. }

and this is the Main method which invoke them..

  1. static void Main(string[] args)
  2. {
  3. // This is test on the DynamicXMLNode
  4. DynamicXMLNodeMain.DynamicXMLNodeCreateReturnValidDynamixXMLNode();
  5. DynamicXMLNodeMain.DynamicXMLNodeConvertToStringReturnXElementValue();
  6. DynamicXMLNodeMain.DynamicXMLNodeTryInvokeMemberCallXElementMethods();
  7. }

C# - DynamicObject with Dynamic的更多相关文章

  1. C# DynamicObject 动态对象

    dynamic是FrameWork4.0的新特性.dynamic的出现让C#具有了弱语言类型的特性.编译器在编译的时候不再对类型进行检查,编译期默认dynamic对象支持你想要的任何特性.比如,即使你 ...

  2. dynamic解析Http xml格式响应数据

    继续上一篇 构建RESTful风格的WCF服务 ,咱已经把服务端的数据和服务准备好了,客户端调用 wcf rest接口后如何解析xml?下面使用dynamic关键字解析来至于WCF REST XML响 ...

  3. 理解C# 4 dynamic(3) – DynamicObject的使用

    上篇文章"理解C# 4 dynamic(2) – ExpandoObject的使用" 了解了ExpandoObject的基本使用. 但ExpandoObject的问题就是它是一个万 ...

  4. 浅谈Dynamic 关键字系列之三(上):ExpandoObject, DynamicObject, DynamicMetaObject

    http://www.cnblogs.com/LoveJenny/archive/2011/07/05/2098578.html ExpandoObject:表示一个对象,该对象包含可在运行时动态添加 ...

  5. Fun with dynamicobject dynamic and the settings table

    What came before In my previous post I discussed ways of making the settings table using Generics to ...

  6. MVC 无法将带 [] 的索引应用于“System.Dynamic.DynamicObject”类型的表达式

    无法将带 [] 的索引应用于“System.Dynamic.DynamicObject”类型的表达式 说明: 执行当前 Web 请求期间,出现未经处理的异常.请检查堆栈跟踪信息,以了解有关该错误以及代 ...

  7. 当类型为dynamic的视图模型遭遇匿名对象

    当年在ASP.NET MVC 1.0时代我提到,在开发时最好将视图的Model定制为强类型的,这样可以充分利用静态检查功能进行排错.不过有人指出,这么做虽然易于静态检查,但是定义强类型的Model类型 ...

  8. 理解C# 4 dynamic(4) – 让人惊艳的Clay

    Clay非常类似于ExpandoObject, 可以看做是ExpandoObject的加强版. 它们能够让我们在不需要定义类的情况下,就构建出我们想要的对象.Clay和ExpandoObject相比, ...

  9. 不一样的dynamic解析json 万能方法

    写过javascript的人都知道js解析json 1:(JSON) 字符串转换为对象. var str = '{"name":"lsw","hobb ...

随机推荐

  1. rtp h264注意点(FU-A分包方式说明)

    前写过一篇文章,分析了h264使用rtp进行封包的格式介绍:RTP封装h264.但里面好像没有把拆分以及一些需要注意的情况说清楚,因此这里做补充,也作为自己的备忘(自己记性好像不太好). 关于时间戳, ...

  2. ES PES TS

    1.流媒体系统结构 ES:elemental stream 基本数据流: PES:packet elemental stream分组的基本数据流: 然后把PES打包成PS ,TS流,PS:progra ...

  3. Dataguard三种保护模式

    Oracle Data Guard 提供三种高水平的数据保护模式来平衡成本.可用性.性能和事务保护.可以使用任意可用管理界面来轻松地设置这些模式.要确定适当的数据保护模式,企业需要根据用户对系统响应时 ...

  4. 转载RabbitMQ入门(6)--远程调用

    远程过程调用(RPC) (使用Java客户端) 在指南的第二部分,我们学习了如何使用工作队列将耗时的任务分布到多个工作者中. 但是假如我们需要调用远端计算机的函数,等待结果呢?好吧,这又是另一个故事了 ...

  5. 【已解决】Android ADT中增大AVD内存后无法启动:emulator failed to allocate memory 8

    [问题] 折腾: [已解决]Android ADT中增大AVD内存后无法启动:emulator failed to allocate memory 8 过程中,增大对应AVD的内存为2G后,结果无法启 ...

  6. C# new用法总结

    有一道这样的题:写出c#中new关键字的三种用法,思前想后挖空心思也只想出了两种用法,回来查了下msdn,还真是有第三种用法: 用于在泛型声明中约束可能用作类型参数的参数的类型,这是在Framewor ...

  7. setImageResource和setImageDrawable区别

    ImageView设置图片的方式有很多钟,可以在xml里面写android:src=”@drawable/xxx”,也可以在java代码里面设置. 在java里面的设置方式也有多种,方法包括:setI ...

  8. Tableau学习笔记之二

    2张图片解析下Tableau 9.0界面的功能 1.数据加载界面: 2.数据分析界面:

  9. 【JSONCpp】简介及demo

    一.JSON简介 JSON 一种轻量级的数据交换格式,易于阅读.编写.解析,全称为JavsScript ObjectNotation. JSON由两种基本结构组成 ①   名字/值 对的集合,可以理解 ...

  10. LeetCode题解——String to Integer(atoi)

    题目: 字符串转换为数字. 解法: 这道题的意思是要考虑到,如果有前置的空字符,则跳过:如果超出数字范围,则返回最大/最小整数:如果碰到第一个不能转换的字符,则返回. 代码: class Soluti ...