.Net 4.o ExpandoObject 使用(下)_转

上篇文章介绍了ExpandoObject的基本使用,本篇文章就ExpandoObject的一些高级的使用进行一些示例。

例子

首先要说的一点,为什么我们在定义动态类型的ExpandoObject时,必须要使用dynamic关键字呢,因为如果我们使用ExpandoObject 进行定义时,那么我们定义的变量就是一个静态类型ExpandoObject的实例化。

下面我们来做个例子就是如何将xml的表示成面向对象的形式。其实在c#3.0中已经提供了Linq To Xml的方式让我们来操作xml,确实比以前的dom方式方便了很多,但是觉得还是看着不太优雅。我们先来看一个Linq To Xml的示例:

01. private XElement CreateByXelement()
02. {
03.     var xelement = new XElement(
04.         "Employee",
05.         new XElement("FirstName","Henry"),
06.         new XElement("LastName","Cui"),
07.         new XElement("Age",23),
08.         new XElement(
09.             "Company",
10.             new XElement("Name","XXXX"),
11.             new XElement("Address","Suzhou China")
12.             )
13.         );
14.     return xelement;
15. }

 

这种方式我觉得是比以前的dom方式更为直观了,但是希望能够以更加优雅的方式来表示:

01. private dynamic CreateByExpandoObject()
02. {
03.     dynamic employee = new ExpandoObject();
04.     employee.FistName="Henry";
05.     employee.LastName="Cui";
06.     employee.Age=23;
07.     employee.Company = new ExpandoObject();
08.     employee.Company.Name="XXXX";
09.     employee.Company.Address="Suzhou China";
10.     return employee;
11. }

转换

也许现在最大的疑问就是想XElement一样提供了Save方法,这里我们来写些辅助的方法进行ExpandoObject到xml的转换吧:

01. private XElement ConvertExpandoObjectToXelement(string eleName, dynamic node)
02. {
03.     var xNode = new XElement(eleName);
04.     foreach (var pro in (IDictionary<string, object>)node)
05.     {
06.         if (pro.Value is ExpandoObject)
07.         {
08.             xNode.Add(ConvertExpandoObjectToXelement(pro.Key, pro.Value));
09.         }
10.         else
11.         {
12.             xNode.Add(new XElement(pro.Key, pro.Value));
13.         }
14.     }
15.     return xNode;
16. }

来看看一个测试:

1. [TestMethod]
2. public void TestExpandoConvert()
3. {
4.    var element =  ConvertExpandoObjectToXelement("Employee"
5.        CreateByExpandoObject());
6.    Console.WriteLine(element.ToString());
7. }

 

我们看到输出结果:

image

好像有点大功告成了,其实远没有这么简单。我们来考虑几个问题,首先如果出现重复的节点怎么办,比如Employee受聘用。我们可以List结合来表示:

01. private dynamic CreateByExpandoObject()
02. {
03.     dynamic employee = new ExpandoObject();
04.     employee.FistName="Henry";
05.     employee.LastName="Cui";
06.     employee.Age=23;
07.     employee.Company = new List<dynamic>();
08.     employee.Company.Add(new ExpandoObject());
09.     employee.Company[0].Name = "XXXX";
10.     employee.Company[0].Address = "Suzhou China";
11.     employee.Company.Add(new ExpandoObject());
12.     employee.Company[1].Name = "YYYY";
13.     employee.Company[1].Address = "Suzhou China";
14.       
15.     return employee;
16. }
然后我们修改下转换增加对List<dynamic>类型的处理:
01. private XElement ConvertExpandoObjectToXelement(string eleName, dynamic node)
02. {
03.     var xNode = new XElement(eleName);
04.     foreach (var pro in (IDictionary<string, object>)node)
05.     {
06.         if (pro.Value is ExpandoObject)
07.         {
08.             xNode.Add(ConvertExpandoObjectToXelement(pro.Key, pro.Value));
09.         }
10.         else
11.         {
12.             if (pro.Value is List<dynamic>)
13.             {
14.                 foreach (var child in (List<dynamic>)pro.Value)
15.                 {
16.                     xNode.Add(ConvertExpandoObjectToXelement(pro.Key, child));
17.                 }
18.             }
19.             else
20.             {
21.                 xNode.Add(new XElement(pro.Key, pro.Value));
22.             }
23.         }
24.     }
25.     return xNode;
26. }

来看看测试的效果:

image

 

API的支持

1)查询

在Linq To Xml中提供了比如:Element、Elements、Descendant、Descendants方法来查询。

而对于我们使用ExpandoObject可以这样:对于单个的属性我们直接通过对象的属性去访问就可以得到了,对于List类型的我们可以使用Linq的语法:

1. var company = from c in (List<dynamic>)CreateByExpandoObject().Company
2.               where c.Name == "XXXX"
3.               select c;
4. Console.WriteLine(company.First().Name);

 

2)修改

对于简单属性的修改直接通过对象的属性就可以去修改了,而对于List<dyniamic>类型:

1. foreach (var child in (List<dynamic>)CreateByExpandoObject().Company)
2.  {
3.      if (child.Name == "XXXX")
4.      {
5.          child.Address = "Shanghai China";
6.      }
7.  }

总结

本文就如何使用ExpandoObject在xml领域中的使用进行了一些示例,只是一个初略的demo,不能说是解决方案。其实我们还可以通过dynamic库中的另外一个类型DynamicObject来实现,实现起来更为优雅,更为方便。在下文中会就DynamicObject操作xml进行一些尝试。

你可能感兴趣的:(object)