本篇文章中就ExpandoObject的基本使用进行一些demo。我们几乎都知道dynamic特性是.net 4.0中一个主要的新特性,而ExpandoObject正是这样的一个动态的类型。ExpandoObject允许我们在实例化之后在运行时进行成员的增加、删除。下面我们来看下基本的使用:

Adding Members

1)实例化

如果需要延迟绑定的话,我们需要用dynamic来定义ExpandpObject的实例化变量,关于dynamic的使用,估计大家都很清楚了。

 

2)增加属性成员

02.public void ExpandoObjectTest()
03.{
04.    dynamic employee = new ExpandoObject();
05.    employee.FirstName = "Henry";
06.    employee.LastName = "Cui";
07.    employee.Age = 23;
08.    Console.WriteLine("Employee's name :{0} age:{1}",
09.        employee.FirstName + employee.LastName,
10.        employee.Age);
11.}

测试的结果:

3)增加Method

在增加方法的时候,先把成员表现成delegate,先看一个没有参数的无返回值的方法:

02.public void ExpandoObjectTest()
03.{
04.    dynamic employee = new ExpandoObject();
05.    employee.FirstName = "Henry";
06.    employee.LastName = "Cui";
07.    employee.Age = 23;
08.    employee.SayHello = (Action)(() => 
09.    {
10.        Console.WriteLine("{0} say \"Hello\" at {1}",
11.            employee.FirstName+" "+employee.LastName,
12.            DateTime.UtcNow.ToString());
13.    });
14.    employee.SayHello();
15.}

在上面的示例中我们将SayHello定义成委托Action类型,并给了默认方法。

下面来看一个有参数、有返回值的:

01.[TestMethod]
02.        public void ExpandoObjectTest()
03.        {
04.            dynamic employee = new ExpandoObject();
05.            employee.FirstName = "Henry";
06.            employee.LastName = "Cui";
07.            employee.Age = 23;
08.            employee.SayHello = (Action)(() => 
09.            {
10.                Console.WriteLine("{0} say \"Hello\" at {1}",
11.                    employee.FirstName+" "+employee.LastName,
12.                    DateTime.UtcNow.ToString());
13.            });
14.  
15.            employee.GetSalary = (Func<int, decimal>)((month) => 
16.            {
17.                if (month > 8)
18.                    return 5000;
19.                return 4000;
20.            });
21.            Console.WriteLine("The employee's october salary is :${0}",
22.                employee.GetSalary(10).ToString());
23.  
24.        }

测试结果:

上面的例子中是段很简单的逻辑就是超过8月份的时候就返回$5000,呵呵。

4)增加Event

在实例中我们定义一个请假事件,员工请假就会上报给经理:

01.[TestClass]
02.   public class DynamicTest
03.   {
04.       [TestMethod]
05.       public void ExpandoObjectTest()
06.       {
07.           dynamic employee = new ExpandoObject();
08.           employee.FirstName = "Henry";
09.           employee.LastName = "Cui";
10.           employee.Age = 23;
11.           employee.SayHello = (Action)(() => 
12.           {
13.               Console.WriteLine("{0} say \"Hello\" at {1}",
14.                   employee.FirstName+" "+employee.LastName,
15.                   DateTime.UtcNow.ToString());
16.           });
17.           employee.GetSalary = (Func<int, decimal>)((month) => 
18.           {
19.               if (month > 8)
20.                   return 5000;
21.               return 4000;
22.           });
23.           employee.AskForLeaveEvent = null;
24.           employee.AskForLeaveEvent += new EventHandler(OnEmployeeLeave);
25.           employee.AskForLeaveEvent(employee,new EventArgs());
26.       }
27.       public void OnEmployeeLeave(object sender, EventArgs e)
28.       {
29.           dynamic em = (dynamic)sender;
30.           Console.WriteLine("Report Manager:{0} is asking for leave", em.FirstName + " " + em.LastName);
31.       }

我们看下运行的结果:

Remove Members

其实ExpandoObject继承了IDictionary<String, Object>的接口,所以我们枚举出在运行时增加的那些成员.

1)枚举出已经存在的成员

我们就来枚举出刚才在employee中增加的成员们:

1.foreach (var pro in (IDictionary<string, Object>)employee)
2.{
3.    Console.WriteLine(pro.Key+" "+pro.Value);
4.}

我们可以看到测试结果:

2)移除成员

其实我们还是利用了ExpandoObject实现了IDictionary接口去实现的,我们移除掉AskForLeaveEvent事件:

1.((IDictionary<string, object>)employee).Remove("AskForLeaveEvent");
2.foreach (var pro in (IDictionary<string, Object>)employee)
3.{
4.    Console.WriteLine(pro.Key+" "+pro.Value);
5.}

我们看看运行的结果:

我们可以看到AskForLeaveEvent被移除了。

总结

本文中主要介绍了ExpandoObject的基本使用,我们发现真的有点动态语言的风味,写过javascript的人感觉会太别爽,呵呵。下文中会就ExpandoObject的原理以及一些扩展就行一些说明。

本篇文章就ExpandoObject的一些高级的使用进行一些示例。

例子

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

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

private XElement CreateByXelement()
{
var xelement = new XElement(
"Employee",
new XElement("FirstName","Henry"),
new XElement("LastName","Cui"),
new XElement("Age",23),
new XElement(
"Company",
new XElement("Name","XXXX"),
new XElement("Address","Suzhou China")
)
);
return xelement;
}

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

private dynamic CreateByExpandoObject()
{
dynamic employee = new ExpandoObject();
employee.FistName="Henry";
employee.LastName="Cui";
employee.Age=23;
employee.Company = new ExpandoObject();
employee.Company.Name="XXXX";
employee.Company.Address="Suzhou China";
return employee;
}

转换

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

private XElement ConvertExpandoObjectToXelement(string eleName, dynamic node)
{
var xNode = new XElement(eleName);
foreach (var pro in (IDictionary<string, object>)node)
{
if (pro.Value is ExpandoObject)
{
xNode.Add(ConvertExpandoObjectToXelement(pro.Key, pro.Value));
}
else
{
xNode.Add(new XElement(pro.Key, pro.Value));
}
}
return xNode;
}

来看看一个测试:

[TestMethod]
public void TestExpandoConvert()
{
var element = ConvertExpandoObjectToXelement("Employee",
CreateByExpandoObject());
Console.WriteLine(element.ToString());
}

我们看到输出结果:

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

private dynamic CreateByExpandoObject()
{
dynamic employee = new ExpandoObject();
employee.FistName="Henry";
employee.LastName="Cui";
employee.Age=23;
employee.Company = new List<dynamic>();
employee.Company.Add(new ExpandoObject());
employee.Company[0].Name = "XXXX";
employee.Company[0].Address = "Suzhou China";
employee.Company.Add(new ExpandoObject());
employee.Company[1].Name = "YYYY";
employee.Company[1].Address = "Suzhou China";
return employee;
}

然后我们修改下转换增加对List<dynamic>类型的处理:

private XElement ConvertExpandoObjectToXelement(string eleName, dynamic node)
{
var xNode = new XElement(eleName);
foreach (var pro in (IDictionary<string, object>)node)
{
if (pro.Value is ExpandoObject)
{
xNode.Add(ConvertExpandoObjectToXelement(pro.Key, pro.Value));
}
else
{
if (pro.Value is List<dynamic>)
{
foreach (var child in (List<dynamic>)pro.Value)
{
xNode.Add(ConvertExpandoObjectToXelement(pro.Key, child));
}
}
else
{
xNode.Add(new XElement(pro.Key, pro.Value));
}
}
}
return xNode;
}

来看看测试的效果:

API的支持

1)查询

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

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

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

2)修改

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

foreach (var child in (List<dynamic>)CreateByExpandoObject().Company)
{
if (child.Name == "XXXX")
{
child.Address = "Shanghai China";
}
}

总结

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

转自:http://henllyee.cnblogs.com/

转: .Net 4.0 ExpandoObject 使用的更多相关文章

  1. var与dynamic

    var与dynamic 如果你用MVC写过程序,那么你应该知道ViewBag这个用于前后台的数据传递工具,那么你是否对ViewBag的用法感到过疑惑呢? ViewBag.Mode1l=new obje ...

  2. ZAM 3D 制作简单的3D字幕 流程(二)

    原地址:http://www.cnblogs.com/yk250/p/5663907.html 文中表述仅为本人理解,若有偏差和错误请指正! 接着 ZAM 3D 制作简单的3D字幕 流程(一) .本篇 ...

  3. ZAM 3D 制作3D动画字幕 用于Xaml导出

    原地址-> http://www.cnblogs.com/yk250/p/5662788.html 介绍:对经常使用Blend做动画的人来说,ZAM 3D 也很好上手,专业制作3D素材的XAML ...

  4. 微信小程序省市区选择器对接数据库

    前言,小程序本身是带有地区选着器的(网站:https://mp.weixin.qq.com/debug/wxadoc/dev/component/picker.html),由于自己开发的程序的数据是很 ...

  5. osg编译日志

    1>------ 已启动全部重新生成: 项目: ZERO_CHECK, 配置: Debug x64 ------1> Checking Build System1> CMake do ...

  6. C#4.0中的dynamic关键字和ExpandoObject对象

    dynamic最大的特点我想莫过于在它的类型在运行时才确定,这也是它与往静态类型关键字的最大区别.如果你在你的代码操作中用到了dynamic关键字去定义一个变量时,那么这个变量在编译的时候编译器不会对 ...

  7. C#与C++的发展历程第二 - C#4.0再接再厉

    系列文章目录 1. C#与C++的发展历程第一 - 由C#3.0起 2. C#与C++的发展历程第二 - C#4.0再接再厉 开始本系列的第二篇,这篇文章中将介绍C#4.0中一些变化,如C++有类似功 ...

  8. C# 4.0四大新特性代码示例与解读

    摘要:今天我们结合代码实例来具体看一下C#4.0中的四个比较重要的特性. 之前的文章中,我们曾介绍过C#的历史及C# 4.0新增特性,包括:dynamic. 命名和可选参数.动态导入以及协变和逆变等. ...

  9. 在MVC控制器里面使用dynamic和ExpandoObject,实现数据转义的输出

    在很多时候,我们在数据库里面定义表字段和实际在页面中展示的内容,往往是不太匹配的,页面数据可能是多个表数据的综合体,因此除了我们在表设计的时候考虑周到外,还需要考虑数据展现的处理.如果是常规的处理,那 ...

随机推荐

  1. win10 uwp 绑定静态属性

    Jasoon 大神问,如何绑定静态属性. 我们经常有静态属性,那么我们如何绑定 假如我们的ViewModel有一个静态属性 public static string CVTE { set; get; ...

  2. win10 uwp smms图床

    本文,如何使用smms图床上传图片,用到win10 uwp post文件,因为我是渣渣,如果本文有错的,请和我说,在本文评论,或发给我邮箱lindexi_gd@163.com,请不要发不良言论 找到一 ...

  3. Python读取SQLite文件数据

    近日在做项目时,意外听说有一种SQLite的数据库,相比自己之前使用的SQL Service甚是轻便,在对数据完整性.并发性要求不高的场景下可以尝试! 1.SQLite简介: SQLite是一个进程内 ...

  4. Java基础总结--变量、运算符总结

    ---变量基本概述----变量作用:就是用来存储数据变量的声明:变量类型 变量名;变量类型---区分不同类型的数据,变量名--按名访问变量变量名(规则):见名识意,第一个字母小写后面驼峰规则变量的作用 ...

  5. LeetCode 62. Unique Paths(所有不同的路径)

    A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below). The ...

  6. Bootstrap的核心——栅格系统的使用

        前  言 絮叨絮叨 Bootstrap 是基于 HTML.CSS.JAVASCRIPT 的,它简洁灵活,使得 Web 开发更加快捷. 而栅格系统是Bootstrap中的核心,正是因为栅格系统的 ...

  7. 关于docker使用的几个小问题(一)

    由于刚接触docker踩了几个坑,希望本文对网瘾少年有所帮助. Docker分CE版(社区版)和EE版(商用版),具体安装流程参考文档介绍,在此不再赘述.下面分Windows和Linux分别踩坑: 一 ...

  8. 安装PyQt5之后mayavi和VTK不能使用

    mayavi在显示数据的过程中需要调用PyQt4的GUI方法产生应用框架.但是新发布的PyQt5和PyQt4在很多方面都是不兼容的,这也就导致了用mayavi编写的程序运行失败.在实践之后,我的解决方 ...

  9. 关于防止sql注入的几个知识点

    1.PDO预处理是首选. 你可以把他看成是要运行的sql的已经编译过的模板,它可以用变量参数进行定制 它有两个显著优点: 1.1:查询仅需解析一次,但可以用相同或者不同参数执行多次.换句话说如果要以不 ...

  10. 利用VS2008发布一个简单的webservice

    一个开发好的webservice,怎样发布出去,供其他电脑访问呢? 本文将介绍如何发布一个简单的webservice,其中的内容都是在网上查看别人文章,自己仿照着做了一遍,因此,难免会发生错误,如果发 ...