




已阅读5页,还剩5页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
VS2010之所以那么强大,究其原因是其背后有着强大的C#4.0作为后台支撑。和以往的所有版本相比,C#4.0的动态性大大增强dynamic就是一个非常明显的例子:(一)dynamic初探:以前因为某些特殊原因,需要动态的调用外部类(假设这个类是实现了某个带有参数的接口函数的),通常我们只能用反射了。示例代码如下:Assembly asm = Assembly.LoadFile(“xxxxx”)asm.CreateInstance(MyAssembly.ClassName).GetType().InvokeMember(Say, BindingFlags.InvokeMethod, null, asm.CreateInstance(MyAssembly.ClassName ), new string aaa );这里顺便简略说一下反射流程:首先通过绝对路径加载某个NET的dll文件,然后创建该assembly中某个class的instance(该 class必须有无参构造函数),获取其类型之后动态调用其函数Say,“BindingFlags.InvokeMethod”表明是一个普通类方 法,“null”的地方是传递一个参数名的,和指明最后的string中的一串values内容一一匹配的可见使用反射调用函数是很痛苦的一件事 情。现在呢?您根本不需要那么麻烦了!因为C#的dynamic会为您做好一切的,下面就是见证奇迹的时刻Assembly asm = Assembly.LoadFile(xxxxx);dynamic dfun = asm.CreateInstance(MyAssembly.ClassName);dfun.Say(Hello!); 注意到咖啡色的代码了么什么?dynamic竟然可以智能感知出动态加载的那个类的方法Say?其实不然:当你按下这个点的时候,IDE是没有智能感 知的,但是如果你知道这个类是有这个方法(因为接口给了其一个契约,必须实现接口中的方法;而接口的方法是公开的),你就可以完全不理会智能感知,照样 写,照样编译通过运行。神奇吧! 看到这里,你就不会认为dynamic和var是“差不多”的概念了(var无非是根据赋值的类型编译器自己判断;且var不能作为函数返回值类型,但是dynamic可以)。 或许有人会疑问:dynamic可以完全替代类似像简单工厂、抽象工厂一类的东西了咯?我的理解是不对!从上面的定义中可以得知:dynamic必须首先获取对象实例,然后动态反射是它做的事情;如果完全取代反射,实例也获取不到,如何反射呢?真是“巧妇难为无米之炊”啊! 说道dynamic可以作为返回值,下面给出一个例子:class DynamicClass public int Num1 get; set; public int Num2 get; set; public DynamicClass(int n1, int n2) Num1 = n1; Num2 = n2; public dynamic DynamicAction get; set; 主函数注意咖啡色部分:static void Main(string args) DynamicClass t = new DynamicClass(1, 2); t.DynamicAction = new Func(x, y) = x + y); Console.WriteLine(t.DynamicAction.Invoke(t.Num1,t.Num2); 道理很简单:因为dynamic类型可以赋值任何东西(包括匿名委托),所以我创建了一个匿名委托给它。然后调用计算结果(匿名委托的调用使用Invoke,可以省略)。 但是dynamic不仅仅可以动态反射类方法和属性,还可以“空中楼阁”般动态地去创建一个类方法和属性,并且赋值,相信吗?这是第二话。(二)神奇的ExpandoObject类和自定义动态类扩展:dynamic在第一话中已经展示它动态根据赋值类型直接自动完成反射的强大功能。现在又是一个新奇迹的诞生static void Main(string args) dynamic d = new ExpandoObject(); d.Name = ServiceBoy; d.Action = Func()=d.Name;); Console.WriteLine(d.Action(); 初看这个代码只是简单的读写Name属性,毫无稀奇可言。但是你注意哦你到MSDN或者你索性new ExpandoObject().Name 试试看,有Name和Action这个属性吗?没有啊,真的没有!嘿,奇了怪了,既然没有,为什么你可以凭空“捏造出一个属性”,而且可以给属性赋 值,并且读取属性内容呢? 俗话说的好天下没有白给的食微软这个类意在向我们揭露一个惊天的大秘密,那就是你可以自定义dynamic类,让这个类跟随你的要求动态的改变自 己(比如增加一个新属性等)。我们可以参照MSDN,给出一个自定义的ExpandoObject:public class SimpleDynamic : DynamicObject Dictionary Properties = new Dictionary(); Dictionary Methods = new Dictionary(); public override bool TryInvokeMember(InvokeMemberBinder binder, object args, out object result) if (!Methods.Keys.Contains(binder.Name) Methods.Add(binder.Name, null); if (args != null) Methodsbinder.Name = args; StringBuilder sbu = new StringBuilder(); foreach (var item in args) sbu.Append(item); result = sbu.ToString(); return true; public override bool TrySetMember(SetMemberBinder binder, object value) if (!Properties.Keys.Contains(binder.Name) Properties.Add(binder.Name, value.ToString(); return true; public override bool TryGetMember(GetMemberBinder binder, out object result) return Properties.TryGetValue(binder.Name, out result); 首先说明这个例子的作用:随意增加不重复的属性并赋值(取值),并且让你随意创建或者调用(带参或无参)函数进行输入(输出)。 分析一下这个类的主要特点: 一般地,任何一个类如果需要动态为自身添加属性、方法等的,就必须实现IDynamicObjectProvidor接口或者是 DynamicObject虚类(之所以用虚类的原因是“各取所需”的缘故,DynamicObject类都通过虚方法virtual去“实现”了接口中 所有的方法,只要继承了这个类,读者可以根据需要“任意”动态覆盖你要的方法)。这里介绍三个最常见的方法: 如果需要支持动态创建写属性,必须覆盖TrySetMember,其方法介绍如下:参数名称作用说明binder:SetMemberBinder类型用于获取动态创建赋值属性的时候“属性名”等一些常见信息(如示例中Name获取动态赋值的那个属性)。value:object类型用于获取设置动态属性的那个值。 如果需要支持动态创建读属性,必须覆盖TryGetMember,其参数作用和TrySetMember大致相当,只是反作用(用于获取某个已有 属性的内容,并且反向传递给object作为输出结果,注意TryGetMember的value是一个out类型)。同时,这个函数多出一个 result类型,用于返回已有属性的存储的值(NULL抛出异常,被认为是错误的)。 如果需要动态调用函数并输出结果,必须覆盖TryInvokeMember方法,此函数比较复杂:参数名称作用说明binder:InvokeMemberBinder类型用于获取动态创建函数时候一些与函数相关的属性:(比如Name是函数名,其中还有一个CallInfo内嵌属性,您还可以获得ArgumentNames(C#4.0中最新的可选参数的名称,通过其ArgumentNameCount获取可选参数名的总个数)。Args:object类型获取动态给函数赋的值。result:object类型返回动态函数执行的结果,Null表示异常。根据以上表格,对照不难读懂我的示例代码现在假设你是这样调用的:1)dynamic d = new SimpleDynamic();d.Name = “Serviceboy”;Console.WriteLine(d.Name);首先创建了一个d的动态类型,然后当赋值给Name的时候,因为Name是属性,所以触发了“TrySetMember”函数,该函数自动检查是否 已经存在这个属性名,如果不存在,则将其添加进入一个Dictionary中并将对应赋予的值传递进去保存起来。当使用输出的时候,同样 地,TryGetMember被触发,系统检测是否预先创建过这个值,如果没有,则抛出异常;存在的话,取出对应的存储value并返回给系统。2)dynamic d = new SimpleDynamic();Console.WriteLine(d.Say(“Hello!”); 首先创建了一个d的动态类型,当动态创建一个方法的时候,系统检测是否包含这个方法名,不包含将添加这个方法名到Dictionary保存,接着检查参数 是否为空,不为空把参数赋值给那个函数名作为Key的Dictionary中保存,最后使用StringBuilder串起来赋值给result作为输 出。下面给出一个比较复杂的例子自定义的XML创建器(仿Jeffery Zhao):public class XmlCreator : DynamicObject public override bool TryInvokeMember(InvokeMemberBinder binder, object args, out object result) /如果除了第一个节点是字符串,后面都是XElement对象,表明此节点是父节点 if (args1 is XElement) XElement root = new XElement(args0.ToString(); /把子节点添加到父节点 for (int i = 1; i args.Length; +i) root.Add(argsi); result = root; /否则是子节点 else /拷贝所有属性到数组: string attributes = new stringbinder.CallInfo.ArgumentNames.Count; for (int i = 0; i binder.CallInfo.ArgumentNames.Count; i+) attributesi = binder.CallInfo.ArgumentNamesi; /拷贝所有属性值到数组: string values = new stringargs.Length - 1; for (int i = 1; i args.Length; +i) valuesi - 1 = argsi.ToString(); XElement subelement = new XElement(args0.ToString(); /属性名称获取 for (int i = 0; i attributes.L
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年3D打印的工业制造
- 工商银行2025淮南市秋招面试典型题目及参考答案
- 2025行业政策环境分析报告
- 邮储银行2025营口市数据分析师笔试题及答案
- 建设银行2025楚雄彝族自治州秋招笔试EPI能力测试题专练及答案
- 邮储银行2025咸阳市秋招笔试英语题专练及答案
- 工商银行2025牡丹江市秋招英文面试题库及高分回答
- 交通银行2025景德镇市信息科技岗笔试题及答案
- 交通银行2025自贡市小语种岗笔试题及答案
- 交通银行2025黔东南苗族侗族自治州秋招笔试性格测试题专练及答案
- 2025年中国航空油料集团招聘笔试模拟题与解析
- 人教版(2024)八年级上册英语Unit 3 Same or Different 教案
- 2025四川省水电投资经营集团有限公司所属电力公司员工招聘6人备考练习题库及答案解析
- 广东省深圳市福田区红岭实验学校(上沙)2025-2026学年八年级上学期开学考试英语试卷(含答案)
- 2025年适老化家居市场分析报告
- 2025年信息系统管理员技术水平考核试题及答案解析
- 社区宣传工作知识培训课件
- 瑜伽相关知识培训课件
- 犬猫免疫知识培训内容课件
- 2025年中国移动式皮带输送机市场调查研究报告
- 2025至2030中国无机絮凝剂行业市场深度研究及发展前景投资可行性分析报告
评论
0/150
提交评论