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

C#4.0中的dynamic关键字和ExpandoObject对象的更多相关文章

  1. 在当前对象中可以使用this关键字指代当前对象

    在当前对象中可以使用this关键字指代当前对象

  2. Java&&As3.0 中的final 关键字

    Java和AS3.0关键字final有“这是无法改变的”或者“终态的”含义,它可以修饰非抽象类.非抽象类成员方法和变量.你可能出于两种理解而需要阻止改变:设计或效率.   可以修饰的对象:   fin ...

  3. C#2.0中使用yield关键字简化枚举器的实现

    我们知道要使用foreach语句从客户端代码中调用迭代器,必需实现IEnumerable接口来公开枚举器,IEnumerable是用来公开枚举器的,它并不实现枚举器,要实现枚举器必需实现IEnumer ...

  4. VS2015 C#6.0 中的那些新特性(转载)

    自动属性初始化 (Initializers for auto-properties) 以前我们是这么写的 为一个默认值加一个后台字段是不是很不爽,现在我们可以这样写 只读属性的初始化(Getter-o ...

  5. C#6.0 中的那些新特性

    C#6.0 中的那些新特性 前言 VS2015在自己机器上确实是装好了,费了老劲了,想来体验一下跨平台的快感,结果被微软狠狠的来了一棒子了,装好了还是没什么用,应该还需要装Xarmain插件,配置一些 ...

  6. C#中Dynamic关键字

    dynamic关键字和动态语言运行时(DLR)是.Net 4.0中新增的功能. 什么是"动态"? 编程语言有时可以划分为静态类型化语言和动态类型化语言.C#和Java经常被认为是静 ...

  7. C#4.0中var和dynamic的区别

    1. var表示“变量的类型是在编译时决定的”, var让你在初始化变量时少输入一些字,编译器会根据右值来推断出变量的类型, var只能用于局部变量的定义,你不能把类的属性定义成 var,也不能把方法 ...

  8. .net 4.0 中的特性总结(一):dynamic

    在新版本的C#中,dynamic关键词是一个很重要的新特性,现在你可以创建动态对象并在运行时再决定它的类型.而且.net 4.0为CLR加入了一组为动态语言服务的运行时环境,称为DLR(Dynamic ...

  9. C#中 dynamic 关键字

       所有表达式都能隐式的转换成dynamic,因为所有的表达式最终都能生成从Object派生出的类型. ; int b = a; //隐式转换错误 int b2 = (int)a; ; int b3 ...

随机推荐

  1. PHP AES/ECB 128加密

    class Security { public static function encrypt($input, $key) { $key=md5($key.md5($key)); $size = mc ...

  2. Spring Boot Dubbo 构建分布式服务

    概述: 节点角色说明 节点 角色说明 Provider 暴露服务的服务提供方 Consumer 调用远程服务的服务消费方 Registry 服务注册与发现的注册中心 Monitor 统计服务的调用次数 ...

  3. UVALive - 3695 Distant Galaxy

    InputThere are multiple test cases in the input file. Each test case starts with one integer N, (1 ≤ ...

  4. STP-10-RPVST+

    RPVST+(快速每VLAN生成树+)是一种以每个VLAN为基础,分别运行RSTP的形式,类似于PVST+.它拥有之前所描述的PVST+的优势,这为RSTP带来了亚秒级的收敛速度.因此,RPVST+和 ...

  5. Codeforces Round #561 (Div. 2) A. Silent Classroom

    链接:https://codeforces.com/contest/1166/problem/A 题意: There are nn students in the first grade of Nlo ...

  6. Mongoose: mpromise (mongoose's default promise library) is deprecated, plug in your own promise library instead: http://mongoosejs.com/docs/promises.html

    操作数据库的时候,老是提示:Mongoose: mpromise (mongoose's default promise library) is deprecated, plug in your ow ...

  7. DOCKER启动失败Job for docker.service failed because the control process exited with error code. See "syste mctl status docker.service" and "journalctl -xe" for details.

    [root@localhost ~]# systemctl start docker Job for docker.service failed because the control process ...

  8. QrenCode : linux命令行下生成二维码图片

    原文链接:http://wowubuntu.com/qrencode.html # 作者:riku/ / 本文采用CC BY-NC-SA 2.5协议授权,转载请注明本文链接. 对于二维码大家应该并不陌 ...

  9. Android Error:Could not run build action using Gradle installation

    错误内容: Error:Could not run build action using Gradle installation ‘D:\AndroidStudio\AS2.x\gradle\grad ...

  10. Yii2.0 两次奇葩的数据库连接经历

    经历一: 公司的项目经过阿里云的ECS升级后,发现在Yii2.0框架中,凡是数据库新增的字段(当然相关的表模型肯定是加了相应字段的),老是报“属性找不到”的问题,最后排查是数据库连接的问题.把127. ...