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

时间:2021-07-21 09:26:56

dynamic最大的特点我想莫过于在它的类型在运行时才确定,这也是它与往静态类型关键字的最大区别。如果你在你的代码操作中用到了dynamic关键字去定义一个变量时,那么这个变量在编译的时候编译器不会对它进行类型检查,允许它到运行的时候再做解释。在大多数情况下,dynamic 类型与object 类型的行为是一样的。但是,不会用编译器对包含 dynamic 类型表达式的操作进行解析或类型检查,只是将有关该变量编译到类型 object 的变量中以及有关它的操作信息打包在一起,在运行时再解释运行。像下面的代码:

dynamic objDynamic = objDynamic + ;//编译通过
object objObject = objObject + ;//编译不通过

原因就是编译器不对dynamic进行类型的检查,这也是两者最大的区别。

dynamic关键字可以用于很多情况,比如在声明中,作为属性、字段、索引器、参数、返回值或类型约束的类型等等,用法和其他基本类型的关键字很相似。

在C#4.0中新添加了一个ExpandoObject对象,它位于程序集:  System.Core(在 System.Core.dll 中)命名空间:  System.Dynamic 中,在传递对象,但是又不想创建一个class或者struct的时候,ExpandoObject就是一个非常好的选择。

例:

dynamic obj = new ExpandoObject();

            obj.orderField = "lp";

            if (brandId != null && brandId != )
obj.brandId = brandId;
if (!string.IsNullOrEmpty(plateNumber))
obj.lp = plateNumber; obj.area = GetAreaLst(sourceIds, startTimes, endTimes); if (sType == && yearIds != null)
obj.modelId = yearIds.Split(',');
else
obj.modelId = new string[] { };  string jsonToSend = JsonConvert.SerializeObject(obj);

注意问题:

由于ExpandObject的先天不足(无特征性):

1. 没有区分的类型名称

2. 没有确切类型定义

如果你看到一个string的函数返回值, 你会想到什么, 你会知道它是一个字符串(这不是废话吗?), 有Length等属性,有IndexOf等方法。

当返回值是MailHelper类对象时,你想只需要直接F12就能看到源码,里面有关于这个类的详细定义,接着你就知道如何使用这个对象了。

当你从一个函数中得到一个ExpandObject的dynamic的返回值时,你知道是什么吗? ExpandObject就是一个黑箱,里面装着什么,谁都不知道。

所以,

1. ExpandObject不能用于太复杂的对象。

ExpandObject最好还是作为简单的数据容器,不要弄得过于复杂,甚至包含有函数处理。

2.ExpandObject的使用范围必须要短

范围短的意思是,产生和使用ExpandObject的代码的路径必须要短(主要是函数调用路径)。如果你正在使用一个ExpandObject对象,查看产生这个ExpandObject的地方,发现分散在好几个函数之中,还有嵌套的话,那么这个ExpandObject是非常难于维护的。

3. ExpandObject的使用场合最好贴近程序的终端。

比如在MVC中的ViewBag, 就是一个好的例子。ViawBag用于生成页面, 而页面就是MVC程序的终端了。到了终端,ExpandObject也就不能*它人了。

正是由于ExpandObject的无特征性,什么都可以做,所以容易导致滥用。

下篇介绍如何通过继承DynamicObject和实现IDynamicMetaObjectProvider,为动态类型添加特征性。

参考:http://blog.csdn.net/xiaogui340/article/details/9339483

http://www.tuicool.com/articles/22qURj