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
我们知道线程池运行时,会不断从任务队列中获取任务,然后执行任务.如果我们想实现延时或者定时执行任务,重要一点就是任务队列会根据任务延时时间的不同进行排序,延时时间越短地就排在队列的前面,先被获取执行. ...
随机推荐
- windows10(x64)+Qt+opencv配置及测试
本电脑系统:Windows10 64位 要下载的文件: 1.Qt 5.6.0 for Windows 32-bit,下载地址:(可以复制链接地址,用迅雷下载,速度快) http://download. ...
- CCF 201612-2 工资计算 java 解题
问题描述 小明的公司每个月给小明发工资,而小明拿到的工资为交完个人所得税之后的工资.假设他一个月的税前工资(扣除五险一金后.未扣税前的工资)为S元,则他应交的个人所得税按如下公式计算: 1) 个人所得 ...
- 修改 Docker 默认网桥地址
在公司里搭建docker测试环境,需要访问内部的服务, 由于网段是172.17.导致该容器没有办法正常访问公司内部服务.翻了一下官方的帮助文档,找到了修改默认网桥地址的办法. 首先停止正在使用的 Do ...
- 几款Z2760平板对比
现阶段的Windows平板本质上分为Windows RT系统平板和完整的Windows 8系统平板两大阵营.RT系统的平板轻薄续航持久,但是由于没法安装常规的.exe程序,所以对于工作需要略显不足,是 ...
- DOS命令大全!
一)MD——建立子目录 1.功能:创建新的子目录 2.类型:内部命令 3.格式:MD[盘符:][路径名]〈子目录名〉 4.使用说明: (1)“盘符”:指定要建立子目录的磁盘驱动器字母,若省略,则为当前 ...
- BackTrack5-r3虚拟机安装
ISOL INUX 3.63 Debian-2008-07-15 Copyright (C) 1994-2008 H. Peter Anvinboot:(按回车) 选择:BackTrack Text ...
- 理解MySQL——索引与优化
转自:理解MySQL——索引与优化 写在前面:索引对查询的速度有着至关重要的影响,理解索引也是进行数据库性能调优的起点.考虑如下情况,假设数据库中一个表有10^6条记录,DBMS的页面大小为4K,并存 ...
- 14——小心copying行为
资源的copying行为决定对象的copying行为. 抑制copying行为,使用引用计数.
- 腾讯优测优分享 | 游戏的UI自动化测试可以这样开展
腾讯优测是专业的自动化测试平台,提供自动化测试-全面兼容性测试,云真机-远程真机租用,漏洞分析等多维度的测试服务,让测试更简单! 对于目前的两大游戏引擎cocos-2dx.unity3D,其UI自动化 ...
- (转)实例简述Spring AOP之间对AspectJ语法的支持(转)
Spring的AOP可以通过对@AspectJ注解的支持和在XML中配置来实现,本文通过实例简述如何在Spring中使用AspectJ.一:使用AspectJ注解:1,启用对AspectJ的支持:通过 ...