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(转)的更多相关文章
- Dart编程实例 - Dynamic 关键字
Dart编程实例 - Dynamic 关键字 void main() { dynamic x = "tom"; print(x); } 本文转自:http://codingdict ...
- 动态编程(Dynamic Programming)
本文素材来自视频,请自备梯子观看:What Is Dynamic Programming and How To Use It Dynamic Programming:动态编程分为如下几步: 将复杂问题 ...
- Java Web学习路线
2016-08-22的早上,本是一个很平静的早上,坐在去往公司的公交车上想到了很多之前上学时的点点滴滴,回想起来还真的是耐人寻味啊,当初青春的懵懂,当初的冲动,当初的做事不考虑后果! 也正是这耐人寻味 ...
- C#(转自wiki)
C#是微软推出的一种基于.NET框架的.面向对象的高级编程语言.C#的发音为"C sharp",模仿音乐上的音名"C♯"(C调升),是C语言的升级的意思.其正确 ...
- 攻城利器 —— Carthage简单介绍
01 Carthage简单介绍 主页:https://github.com/Carthage/Carthage.git 作者:Justin Spahr-Summers等 版本:0.18 目标:用最简单 ...
- C#与.Net Framework的各种版本和联系
C#是微软公司发布的一种面向对象的.运行于.NET Framework之上的高级程序设计语言.并定于在微软职业开发者论坛(PDC)上登台亮相.C#是微软公司研究员Anders Hejlsberg的最新 ...
- C# 发展史
C# 发展史 Intro 本文主要总结介绍C# 每个版本带来的不同的语言特性. C#,读作C Sharp,是微软推出的一种基于.NET平台的.面向对象的高级编程语言.是微软公司在2000年发布的一种新 ...
- 论文 ClickP4: Towards Modular Programming of P4 小结
当前P4存在的问题(ClickP4为解决的问题) 1.随着P4程序的规模和复杂性的增加,从零开始开发单片P4程序容易出错,需要相当多的时间和精力去解决,所以网络政策的多样性和动态性使得运营商为了满足要 ...
- 【RL系列】MDP与DP问题
推荐阅读顺序: Reinforcement Learning: An Introduction (Drfit) 有限马尔可夫决策过程 动态编程笔记 Dynamic programming in Py ...
- C#学习笔记12
1.在使用反射时,反射可以绕过安全访问级别(private.protected)修饰的类或属性,来获取需要的信息. 2.泛型的反射:可以使用Type.ContainsGenericParameters ...
随机推荐
- 通过数据库方式访问excel 2007及其以后(xlsx)文件的连接字符串
sqlconn.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=D:\test3.xls;Extended Properties=&q ...
- 三种实例化委托的方式(C# 编程指南)
1.定义的委托和方法 delegate void TestDelegate(string s); static void M(string s) { Console.WriteLine(s); } 2 ...
- 高校手机签到系统——第一部分Authority权限系统(下)
很抱歉,之前寝室光纤断了,所以到现在才更新这个系列的第二篇博客.点击访问高校手机签到系统——第一部分Authority权限系统(上) 这几天我反思了一下上一篇写博上的方式,一味的贴代码式的,是否应该更 ...
- java并发:中断一个正在运行的线程
要使任务和线程能安全可靠地停止,并不是一件很容易的事情,java没有提供任何机制来安全地终止线程,那么我们该怎么办呢? 下面我们先来了解一下java中的中断机制: java中断机制是一种协作机制,也就 ...
- 第五章 与众不同的this
我们来看下面的代码: ①var name="windows"; function myfun() //定义一个函数myfun { console.log("I'm &qu ...
- http长链接与短链接
http://www.cnblogs.com/cswuyg/p/3653263.html keep-live模式 这个博客写的很全:http://www.cnblogs.com/skynet/arch ...
- Javascript基础系列之(三)数据类型 (数值 Number)
javascript中想限定一个数的数值,无需限定它是整数还是浮点数型 var num1 = 80 ; var num2 = 55.51; var num3 = -34; var num4 = 9e5 ...
- Java-对象池
对象池使用的基本思路是:将用过的对象保存起来,等下一次需要这种对象的时候,再拿出来重复使用,从而在一定程度上减少频繁创建对象所造成的开销. 并非所有对象都适合拿来池化――因为维护对象池也要造成一定开销 ...
- Java基础-常量池
在class文件中,“常量池”是最复杂也最值得关注的内容. Java是一种动态连接的语言,常量池的作用非常重要,常量池中除了包含代码中所定义的各种基本类型(如int.long等等)和对象型(如Stri ...
- array,vertor,arraylist,hashable,hashmap等几个易混淆概念的区别
Array可以存放Object和基本数据类型,但创建时必须指定数组的大小,并不能再改变, Vertor是放的Object. Vertor一维,Hashmap/Hashtabe二维: Vertor/Ar ...