C#编程总结(十四)dynamic
http://www.cnblogs.com/yank/p/4177619.html
C#编程总结(十四)dynamic
介绍
Visual C# 2010 引入了一个新类型 dynamic。 该类型是一种静态类型,但类型为 dynamic 的对象会跳过静态类型检查。 大多数情况下,该对象就像具有类型 object 一样。 在编译时,将假定类型化为 dynamic 的元素支持任何操作。 因此,您不必考虑对象是从 COM API、从动态语言(例如 IronPython)、从 HTML 文档对象模型 (DOM)、从反射还是从程序中的其他位置获取自己的值。 但是,如果代码无效,则在运行时会捕获到错误。
var与dynamic对比
1、var编译时替换为实际类型,而dynamic实际是object类型。
一旦被编译,编译期会自动匹配var 变量的实际类型,并用实际类型来替换该变量的申明,这看上去就好像我们在编码的时候是用实际类型进行申明的。而dynamic被编译后,实际是一个object类型,只不过编译器会对dynamic类型进行特殊处理,让它在编译期间不进行任何的类型检查,而是将类型检查放到了运行期。
2、智能感知。
以var声明的变量,支持“智能感知”,因为visual studion能推断出var类型的实际类型,而以dynamic声明的变量却不支持“智能感知”,因为编译器对其运行期的类型一无所知。对dynamic变量使用“智能感知”,会提示“此操作将在运行时解析”。
简单案例
编写一个hello world的测试程序,定义DynamicTest类型,并增加Welcome方法,其参数为name.
然后创建dynamic对象,调用Welcome方法。参数为空。
using System; namespace DynamicSample
{
class Program
{
static void Main(string[] args)
{
dynamic obj = new DynamicTest();
obj.Welcome();
}
} class DynamicTest
{
public void Welcome(string name)
{
Console.WriteLine("Hello {0},welcome to dynamic world.",name);
}
}
}

看看发生什么事情呢,通过测试发现:
编译通过,没有任何异常。
运行时抛出异常,异常信息:
未处理Microsoft.CSharp.RuntimeBinder.RuntimeBinderException
HResult=-2146233088
Message=“Welcome”方法没有采用“0”个参数的重载
Source=Anonymously Hosted DynamicMethods Assembly
StackTrace:
在 CallSite.Target(Closure , CallSite , Object )
在 System.Dynamic.UpdateDelegates.UpdateAndExecuteVoid1[T0](CallSite site, T0 arg0)
在 DynamicSample.Program.Main(String[] args) 位置 E:\Donet\C#\DynamicSample\DynamicSample\Program.cs:行号 13
在 System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
在 System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
在 Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
在 System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
在 System.Threading.ThreadHelper.ThreadStart()
InnerException:

修正后:
class Program
{
static void Main(string[] args)
{
dynamic obj = new DynamicTest();
string name = "Tom";
obj.Welcome(name); Console.WriteLine("Input any key to exit.");
Console.ReadKey();
}
}

运行结果:

如果改为var,定义该对象,并调用方法,代码如下,编译器会报错:
var v1 = new DynamicTest();
v1.Welcome();
错误信息:
错误 CS7036 未提供与“DynamicTest.Welcome(string)”的必需形参“name”对应的实参 DynamicSample Program.cs 15
错误 CS7036 There is no argument given that corresponds to the required formal parameter 'name' of 'DynamicTest.Welcome(string)' DynamicSample
dynamic应用范围
1、在声明中,作为属性、字段、索引器、参数、返回值或类型约束的类型,都可以使用dynamic。
2、在显式类型转换中,作为转换的目标类型。任何对象都可以隐式转为dynamic。
3、在以类型充当值(如 is 运算符或 as 运算符右侧)或者作为 typeof 的参数成为构造类型的一部分的任何上下文中。
通过一个实例来具体说明:
class DynamicUser
{
/// <summary>
/// 字段
/// </summary>
public dynamic userid; /// <summary>
/// 属性
/// </summary>
public dynamic UserName { get; set; } /// <summary>
/// 玩游戏
/// (dynamic可以作为参数、返回值等)
/// </summary>
/// <param name="game"></param>
/// <returns></returns>
public dynamic Play(dynamic game)
{
dynamic defaultGame = "Play Basketball."; dynamic secGame = "Play with mud."; if (game is int)
{
return defaultGame;
}
else
{
return secGame;
}
}
/// <summary>
/// 显式类型转换
/// </summary>
public void ConvertToDynamic(object obj)
{
dynamic d;
d = (dynamic)obj;
Console.WriteLine(d);
}
/// <summary>
/// 类型判定
/// (dynamic 可以使用is、as、typeof)
/// </summary>
public void TypeCheck()
{
int age = 20;
Console.WriteLine("Age is Dynamic? {0}",age is dynamic); dynamic d = age as dynamic;
Console.WriteLine("Age:{0}",d); Console.WriteLine("List<dynamic>'s type is {0}",typeof(List<dynamic>));
} }

测试用例:
DynamicUser user = new DynamicUser();
user.userid = 123;
user.UserName = "Lucy";
user.ConvertToDynamic(user.userid);
user.ConvertToDynamic(user.UserName);
user.TypeCheck(); Console.WriteLine("Input any key to exit.");
Console.ReadKey();

测试结果:
dynamic的执行效率
关于dynamic的效率问题,这里暂不展开,后续专门来讨论...
应用
1、自动反射
2、COM组件互操作
3、混合编程,例如IronRuby和IronPython
4、处理Html DOM对象
5、还有一种应用,数据传输中格式转换,如:对象转json等,很方便
C#编程总结(十四)dynamic的更多相关文章
- 学习ASP.NET Core Razor 编程系列十四——文件上传功能(二)
学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET ...
- ~~并发编程(十四):Queue~~
进击のpython ***** 并发编程--Queue 进程其实就提过这个Queue的问题,我们为什么在进程使用Queue? 是因为当时我们想要对共享数据进行修改,同时也希望它能够自动的给我加个锁 基 ...
- Java并发编程(十四)-- 线程池实现原理
在上一章我们从宏观上介绍了ThreadPoolExecutor,本文将深入解析一下线程池的具体实现原理 原理解析 线程池状态 在ThreadPoolExecutor中定义了一个volatile变量,另 ...
- Java并发编程(十四)Java内存模型
1.共享内存和消息传递 线程之间的通信机制有两种:共享内存和消息传递:在共享内存的并发模型里,线程之间共享程序的公共状态,线程之间通过写-读内存中的公共状态来隐式进行通信.在消息传递的并发模型里,线程 ...
- C#编程(十四)----------构造函数
原文链接:http://blog.csdn.net/shanyongxu/article/details/46501683 构造函数 所谓的构造函数就是和类名重名的且没有返回值的方法. class P ...
- C#高级编程五十四天----Lookup类和有序字典
Lookup类 Dictionary<Tkey,TValue>仅仅为每一个键支持一个值.新类Lookup<Tkey,TValue>是.NET3.5中新增的,它类似与Dictio ...
- 【读书笔记】C#高级编程 第二十四章 文件和注册表操作
(一)文件和注册表 对于文件系统操作,相关的类几乎都在System.IO名称空间中,而注册表操作由System.Win32名称空间中的类来处理. (二)管理文件系统 System.MarshalByR ...
- java并发编程(十四)同步问题的内存可见性
转载请注明出处:http://blog.csdn.net/ns_code/article/details/17288243 加锁(synchronized同步)的功能不仅仅局限于互斥行为,同时还存在另 ...
- java 面向对象编程--第十四章 多线程编程
1. 多任务处理有两种类型:基于进程和基于线程. 2. 进程是指一种“自包容”的运行程序,由操作系统直接管理,直接运行,有自己的地址空间,每个进程一开启都会消耗内存. 3. 线程是进程内部单一的 ...
- 并发编程(十四)—— ScheduledThreadPoolExecutor 实现原理与源码深度解析 之 DelayedWorkQueue
我们知道线程池运行时,会不断从任务队列中获取任务,然后执行任务.如果我们想实现延时或者定时执行任务,重要一点就是任务队列会根据任务延时时间的不同进行排序,延时时间越短地就排在队列的前面,先被获取执行. ...
随机推荐
- 2015-2016最火的Android开源项目--github开源项目集锦(不看你就out了)
标签: Android开发开源项目最火Android项目github 2015-2016最火的Android开源项目 本文整理与集结了近期github上使用最广泛最火热与最流行的开源项目,想要充电与提 ...
- php生成html文件的多种方法介绍
我经常会在网上看到有人问怎么将整个动态的网站静态化,其实实现的方法很简单. 代码如下 复制代码 <?php//在你的开始处加入 ob_start(); ob_start(); //以下是你的代 ...
- Apache Tomcat开机后台启动
作为软件开发人员,经常接触Tomcat,完成的项目,需要部署到服务器上的Tomcat,才能供其他人访问浏览. 因为存在以下问题,所以需要把Tomcat设置为后台自动启动: 1.服务器可能因环境故障面临 ...
- Best Coder Round#25 1001 依赖检测
原题大致上就是检测一系列进程之间是否存在循环依赖的问题,形如: a->b->c->a, a->a ,都行成了循环依赖,事实上可以视为“检测链表中是否存在环” AC代码: #i ...
- SQL 基本知识
四个基础语法 1. insert into 表名 (列名) [values] 值列表 insert into 表名 values 值列表 [扩展]插入多行: 1. insert into <表名 ...
- 虚机centos和本机Windows之间文件的拷贝无法用xftp时用FileZilla也行
步骤如下: 1.如果Centos没有安装ssh,则需要先安装: 2.查看虚拟机中IP地址,命令如下: ifconfig 3.在windows中安装ftp软件 FileZilla启动软件如图: 6 这 ...
- java 接口
1.接口的引出:发现没有继承关系的类也能共享行为 2.接口不是类,类描述对象的属性和行为,但是接口只关注实现的行为3.当我们发现有行为在多个没有继承关系的类中共享,我们要把它抽取到接口中,而不是写到父 ...
- bookstore网上书店测试缺陷报告2
Bookstore网上书店系统测试缺陷报告 缺陷编号 01.01.0002 发现人 吴赵昕 记录日期 2016-06-10 所属模块 购物车 确认人 吴赵昕 确认日期 2016-06-10 当前状 ...
- OD20
查壳 发现没有壳 那就载入OD 在命令中在API函数下下个断点 然后程序跑起来 , 点CHECK 断下来了 在动态链接库断下来了 我们alt+F9 回到用户界 ...
- 小学生四则运算出题程序 无操作界面java版 简单的运用java中一些基本操作
这是本学期java课中实验大纲里的第一个实验,这里简单做了一个无用户界面版本. import java.util.Random; import java.util.Scanner; public cl ...