C#高级编程七十二天----DynamicObject和ExpandoObject

DynamicObject和ExpandoObject

1.ExpandoObject表示一个对象,该对象包含可在运行时动态添加和移除的成员.这个类和动态类型有关,这个类能做些什么?

案例:

//ExpandoObject这个类需要引入System.Dynamic;

dynamic dynEO = new ExpandoObject();

dynEO.number = 20;

dynEO.Method = new Func<int, string>((int i) => { return (i + 20).ToString(); });

Console.WriteLine(dynEO.number);

Console.WriteLine(dynEO.Method(dynEO.number));

Console.ReadKey();

ExpandoObject这个累还是很有用的,他可以动态的添加成员和方法,这样我们就可以在写一些对象时,不需要在new一个class那么麻烦,只要这个类就OK了,不过有一点要注意,这个类时在运行时解析的,这样我们就会带来性能上的一些损失,而且,程序的逻辑复杂性越高,越难发现问题所在,所以,对于简单的对象,我们可以使用这个类,复杂的就不要使用了.

2.DynamicObject

DynamicObject跟ExpandoObject最大的区别就是,我们可以通过继承DynamicObject,自己来决定动态对象如何执行.咱先来看一下DynamicObject的定义中初始化函数:

public class DynamicObject:IDynamicObjectProvider

{

protected DynamicObject();

}

可以看到的是我们不可以对DynamicObject直接实例化,这也是DynamicObject设计的初衷,有我们自己来决定运行时的动态的成员的处理.一般的时候如果我们自定义的类型只需要处理一些动态的属性的时候我们只需要重写TryGetMember和TrySetMember这两个方法.

using System;

using System.Collections.Generic;

using System.Dynamic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

namespace Dynamic和Expando

{

class Program

{

static void Main(string[] args)

{

dynamic employee = new Test();

employee.Name = "zhangsan";

employee.Age = "22";

employee.Sex = "Man";

Console.WriteLine("name : {0} , age = {1} , sex = {2}",employee.Name,employee.Age,employee.Sex);

Console.ReadKey();

}

}

public class Test : DynamicObject

{

Dictionary<string, object> dic = new Dictionary<string, object>();

/*

* 这里重写TryGetMember和TrySetMember方法,继承了DynamicObject后,

* 可以override一大堆TryXXX的方法了

*/

public override bool TryGetMember(GetMemberBinder binder, out object result)

{

var name = binder.Name;

Console.WriteLine("获取 {0}",name);

return dic.TryGetValue(name, out result);

}

public override bool TrySetMember(SetMemberBinder binder, object value)

{

var name = binder.Name;

dic[name] = value;

Console.WriteLine("写入 {0} = {1}",name,value);

return true;

}

}

}

我们还可以重写DynamicObject中的其他许多方法,实现我们动态运行时的操作.通过重写里面的方法实现我们动态运行时的自定义操作,这样我们可以更多的趋势线自己的一些动态的组件.

我是个比较啰嗦的人,我觉得有必要去分析一下冲下的那两个方法:TryGetMember和TrySetMember

TrySetMember方法:为设置成员值的操作提供实现.从DynamicObject类派生的类可以重写此方法,以便为诸如设置属性值这样的操作指定动态行为.

TryGetMember方法:提供了实现的操作得到成员的值.继承DynamicObject的类可以覆盖这个方法来制定动态行为等操作得到一个属性的值.

简单说,TryGetMember得到值,TrySetMember设置值.

TryGetMember(GetMemberBinder binder, out object result) 方法实现对数据的获取,binder.Name就是获取的属性的名称,result是获取的属性值.通过binder.Name在Data中获取到对应的属性值,传出到外面(能看到result是out参数)

TrySetMember(SetMemberBinder binder, object value) 对存在的属性进行赋值.

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-28 23:53:20

C#高级编程七十二天----DynamicObject和ExpandoObject的相关文章

C++面向对象高级编程(七)point-like classes和function-like classes

技术在于交流.沟通,转载请注明出处并保持作品的完整性. 1.pointer-like class 类设计成指针那样,可以当做指针来用,指针有两个常用操作符(*和->),所以我们必须重载这两个操作 /*简单实现一下智能指针的*与 -> 操作符*/ template <class T> class shared_ptr_test { public: T& operator* () const //重载* { return *px; } T* operator->() co

C#高级编程八十二天----用户自定义异常类

用户自定义异常类 前面已经说了不少关于异常的问题了,现在来给大家说一下自定义异常时咋个回事以及咋样. 为啥会出现自定义异常类呢?用用脚趾头想想也明白,是为了定义咱们自己的异常,自定义异常类继承自ApplicationException 首先异常(Exception)分为两大类,一个是预定义的异常类,后者是用户自定义异常类时需要继承的类. 案例: using System; using System.Collections.Generic; using System.Linq; using Sys

C#高级编程五十二天----有序列表

有序列表 如果需要基于对所有集合排序,就可以使用SortedList<TKey,TValue>类.这个类按照键给元素排序.这个集合中的值和键都可以使用任意类型. 下面的例子创建了一个有序列表,其中键和值类型都是string.默认的构造函数创建了一个空列表,再用Add()方法添加书.使用重载的构造函数.可以定义列表的容量,传递实现了IComparer<TKey>接口的对象,该接口用于给列表中的元素排序. 使用Add(Tkey,Tvalue)方法,第一个参数是键,第二个参数是值.除了使

C#高级编程七十五天----C#使用指针

在C#中使用指针的语法 假设想在C#中使用指针,首先对项目进行过配置: 看到属性了吗?单击: 看到那个同意不安全代码了吗?选中 然后将有关指针,地址的操作放在unsafe语句块中.使用unsafekeyword是告诉编译器这里的代码是不安全的. unsafekeyword的使用: (1)放在函数前,修饰函数,说明在函数内部或函数的形參涉及到指针操作: unsafe static void FastCopy(byte[] src, byte[] dst, int count) { // Unsaf

C#高级编程六十二天----LINQ标准的查询操作符

LINQ标准的查询操作符 首先我们来看一下LINQ的操作符,可根据查询操作符的操作"类型"进行分类,如把它们分成投影,限制,排序,联接,分组,串联,聚合,集合,生成,转换,元素,相等,量词,分割等. 类型 操作符名称 投影操作符 Select,SelectMany 限制操作符 Where 排序操作符 OrderBy,OrderByDescending,ThenBy,ThenByDescending,Reverse 联接操作符 Join,GroupJoin 分组操作符 GroupBy 串

C#高级编程七十一天----DLR ScriptRuntime

包含DLR ScriptRuntime DLR是微软的一个开源项目.为.NET影城程序提供了动态脚本注入支持.DLR构建的功能包含两个方面,一个是共享的动态类型系统,一个是标准的承载模型.但是VS并没有继承相关的DLL,大家可以从Codeplex获得源码.这里不得不提及CLR,它是整个运行环境的基础,DLR也是运行在其上,这样是由显而易见的好处的,CLR的垃圾垃圾回收,JIT编译,安全模式,DLR也能享用这些底层架构功能,如果我们对垃圾回收进行优化,或者是提供某种功能,那么DLR相应的也能享用这

C#高级编程七十天----dynamic类型

dynamic类型 C#新增了dynamic关键字,正是因为这一个小小的关键字,C#像前迈进了一大步. dynamic是一个类型关键,声明为dynamic的类型与"静态类型"(这里的静态是指编译时确定的类型,例如int,double类型)相比最大的特定它是"动态类型",它会在运行时尝试调用方法,这些方法的存在与否不是编译时期检查的,而是在运行时查找,如果方法存在并且参数正确,会正确调用,否则会抛出异常. 案例: dynamic d = Console.Out; dy

Unix环境高级编程(七)fork函数总结

在Unix/Linux中用fork函数创建一个新的进程.进程是由当前已有进程调用fork函数创建,分叉的进程叫子进程,创建者叫父进程.该函数的特点是调用一次,返回两次,一次是在父进程,一次是在子进程.两次返回的区别是子进程的返回值为0,父进程的返回值是新子进程的ID.子进程与父进程继续并发运行.如果父进程继续创建更多的子进程,子进程之间是兄弟关系,同样子进程也可以创建自己的子进程,这样可以建立起定义关系的进程之间的一种层次关系. 程序包含位于内存的多个组成部分,执行程序的过程将根据需要来访问这些

C#高级编程八十二天----用户自己定义异常类

用户自己定义异常类 前面已经说了不少关于异常的问题了,如今来给大家说一下自己定义异常时咋个回事以及咋样. ? 为啥会出现自己定义异常类呢? 用用脚趾头想想也明确,是为了定义咱们自己的异常,自己定义异常类继承自ApplicationException? 首先异常(Exception)分为两大类,一个是提前定义的异常类,后者是用户自己定义异常类时须要继承的类. 案例: ? using?System; using?System.Collections.Generic; using?System.Lin