转: .Net 4.0 ExpandoObject 使用
本篇文章中就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 使用的更多相关文章
- var与dynamic
var与dynamic 如果你用MVC写过程序,那么你应该知道ViewBag这个用于前后台的数据传递工具,那么你是否对ViewBag的用法感到过疑惑呢? ViewBag.Mode1l=new obje ...
- ZAM 3D 制作简单的3D字幕 流程(二)
原地址:http://www.cnblogs.com/yk250/p/5663907.html 文中表述仅为本人理解,若有偏差和错误请指正! 接着 ZAM 3D 制作简单的3D字幕 流程(一) .本篇 ...
- ZAM 3D 制作3D动画字幕 用于Xaml导出
原地址-> http://www.cnblogs.com/yk250/p/5662788.html 介绍:对经常使用Blend做动画的人来说,ZAM 3D 也很好上手,专业制作3D素材的XAML ...
- 微信小程序省市区选择器对接数据库
前言,小程序本身是带有地区选着器的(网站:https://mp.weixin.qq.com/debug/wxadoc/dev/component/picker.html),由于自己开发的程序的数据是很 ...
- osg编译日志
1>------ 已启动全部重新生成: 项目: ZERO_CHECK, 配置: Debug x64 ------1> Checking Build System1> CMake do ...
- C#4.0中的dynamic关键字和ExpandoObject对象
dynamic最大的特点我想莫过于在它的类型在运行时才确定,这也是它与往静态类型关键字的最大区别.如果你在你的代码操作中用到了dynamic关键字去定义一个变量时,那么这个变量在编译的时候编译器不会对 ...
- C#与C++的发展历程第二 - C#4.0再接再厉
系列文章目录 1. C#与C++的发展历程第一 - 由C#3.0起 2. C#与C++的发展历程第二 - C#4.0再接再厉 开始本系列的第二篇,这篇文章中将介绍C#4.0中一些变化,如C++有类似功 ...
- C# 4.0四大新特性代码示例与解读
摘要:今天我们结合代码实例来具体看一下C#4.0中的四个比较重要的特性. 之前的文章中,我们曾介绍过C#的历史及C# 4.0新增特性,包括:dynamic. 命名和可选参数.动态导入以及协变和逆变等. ...
- 在MVC控制器里面使用dynamic和ExpandoObject,实现数据转义的输出
在很多时候,我们在数据库里面定义表字段和实际在页面中展示的内容,往往是不太匹配的,页面数据可能是多个表数据的综合体,因此除了我们在表设计的时候考虑周到外,还需要考虑数据展现的处理.如果是常规的处理,那 ...
随机推荐
- mac 通过brew安装php70 +php-fpm+ phalcon3.0.3
安装php7.0.15 brew install homebrew/php/php70 brew install homebrew/php/php70-mcrypt brew install home ...
- Java继承--子父类中的构造函数
子父类中的构造函数的特点: 1.在子类构造对象时,发现,访问子类构造函数时,父类构造函数也运行了. 原因是:在子类的构造函数中第一行有一个默认的隐式语句. super(); 类似于this(); ...
- 2017年十大奇葩画风的H5页面案例,原来脑洞可以这样大
每个人都是视觉动物,画面精美.体验奇特的H5,用户在内心一般都会满分打出,毫不吝啬,同时也毫不犹豫分享,因为此时的分享不掉价儿~ 今天给大家准备了十支H5,画风超级奇特,非常值得一看所有案例均可在19 ...
- HTML之头部标签
<header> head 元素元素包含了所有的头部标签元素 可以添加在头部区域的元素标签为: title,style,meta,link,script,noscript,base < ...
- Linux入门(12)——解决双系统下Ubuntu16.04不能访问Windows分区
解决办法一: 进入windows系统,关闭快速启动,关机. 解决办法二: 如果办法一不能解决问题,用这个办法. 查看盘符: sudo fdisk -l 需要在查看盘符后记下目标盘符的数字,比如想解除C ...
- Oracle12C如何启动PDB数据库
在启动PDB类型的数据库之前需要用管理员账号[即:sys 或者system管理员账户登录进去CDB数据库,以下命令是在PLSQL登录进去CDB数据库的dos命令行执行的] alter pluggab ...
- escape、encodeURI和encodeURIComponent的区别及使用
编码 javascript中的编码函数有三种 escape(string) encodeURI(string) encodeURIComponent(string) 解码 相应的解码函数也有以下三种 ...
- PHP设计模式三:原型设计模式
一.什么是原型设计模式 原型设计模式使用一种克隆技术来复制实例化的对象,新对象是通过复制原型实例创建的.原型设计模式的目的是通过使用克隆以减少 实例化对象的开销. 在原型设计模式中,Client类是不 ...
- python函数前篇
函数:函数是指将一组语句的集合通过一个函数名封装起来,要想执行这个函数,只需调用其函数名即可 函数特性: 减少重复代码 使程序变得可扩展 使程序变得易维护 什么是函数? 函数就是具备某一特定功能的工具 ...
- [Bayesian] “我是bayesian我怕谁”系列 - Exact Inferences
要整理这部分内容,一开始我是拒绝的.欣赏贝叶斯的人本就不多,这部分过后恐怕就要成为“从入门到放弃”系列. 但,这部分是基础,不管是Professor Daphne Koller,还是统计学习经典,都有 ...