C#编程(七十)----------dynamic类型
原文链接 ; http://blog.csdn.net/shanyongxu/article/details/47296033
dynamic类型
C#新增了dynamic关键字,正是因为这一个小小的关键字,C#像前迈进了一大步.
dynamic是一个类型关键,声明为dynamic的类型与”静态类型”(这里的静态是指编译时确定的类型,例如int,double类型)相比最大的特定它是”动态类型”,它会在运行时尝试调用方法,这些方法的存在与否不是编译时期检查的,而是在运行时查找,如果方法存在并且参数正确,会正确调用,否则会抛出异常.
案例:
dynamic d = Console.Out;
dynamic a;
a = new Int32();
int b = a;
a++;
a--;
//这是东西不会有自动补全,因为必须在运行的时候才能检查方法的正确性
d.WriteLine("hello,world");
//所以大小写全靠自己
d.WriteLine(d.GetType());
//d.writeline();在运行的时候会抛出异常
对dynamic类型的操作只能有以下几种:
1.赋值
2.方法调用
3.自增,自减
4.接受”静态类型”的构造器创建的对象
与关键字var比较
从表面上看,dynamic与var关键字的用法很像,但实质上有本质区别.
var关键字被称为:隐含类型局部变量(Local Variable Type Inference),var只能用作局部变量,不能用于字段,参数;声明的同时必须初始化;初始化时类型就已经确定了,并且不能再被赋值不能进行隐式类型转换的类型的数据;编译时编译器会对var定义的变量进行类型推断,这时变量的类型已经确定.
dynamic可用于类型的字段,方法参数,方法返回值,可用于泛型的类型参数等;可以赋值给或被赋值任何类型并且不需要显式的强制类型转换,因为这些是运行时执行的,这要得益于dynamic类型的动态特性.
与反射的比较
首先能看到的是,dynamic与反射相比,执行相同操作所需的代码少得多.
如调用类Me中的GetName()方法:
//用反射调用GetName()方法,这里需要使用命名空间System.Reflection
Assembly a = Assembly.GetExecutingAssembly();
object instance = a.CreateInstance("Xianfen.NET.TestDynamic.Me");
Type type = instance.GetType();
MethodInfo mi = type.GetMethod("GetName");
object result = mi.Invoke(instance, null);
同样的dynamic调用:
dynamic myInfo = new Me();
string result = myInfo.GetName();
dynamic类型与反射相比能进行的操作要少的多.
目前dynamic类型对属性调用是不可用的,但我们知道,属性生成IL时,对属性的读或者写会生成对象的在属性名前加上get_或set_前缀生成相应的方法,尝试调用两个方法来访问属性:
dynamic myInfo = new Me();
myInfo.set_Blog("hello,world");
string result = myInfo.get_Blog();
会抛出异常,提示找不到get/set_Blog方法,这点比较遗憾,同样,对有参属性的访问也是不行的.
反射还可以访问私有方法字段以及其他类型成员以及取得类型以及类型成员的信息等.
动态类型dynamic带给.net程序员的是更方便和快捷,为自己的程序书写带来了极大的便利.可到底怎么用?好不好用?效率高不高?这才是大家关注的.
var和dynamic简介
1.var简介:其实也就是弱化类型的定义,在代码编译时候确定类型
2.dynamic简介:动态类型,在代码运行的时候确定类型.
var和dynamic区别
1.var程序编译时确定类型,dynamic程序运行时确定类型
2.var只能定义局部变量,dynamic可定义局部变量和类变量.
var,dynamic,传统确定类型的效率对比
传统类型的效率>=var动态类型>dynamic动态类型
小小总结:
常有人会拿var和dynamic作比较,实际上,var和dynamic完全是两个概念,根本不应该放在一起比较.var实际上是编译期抛给我们的”语法糖”,一旦被编译,编译期会自动匹配var变量的实际类型,并用实际类型来替换该变量的声明,这看上去就好像我们在编码的时候用实际类型进行声明的.而dynamic被编译后,实际是一个object类型,只不过编译器会对dynamic类型特殊处理,让它在编译期间不进行任何的类型检查,而是将类型检查放到了运行期.
这从VS的编辑器窗口就能看出来.以var声明的变量,支持”智能感知”,因为VS能推断出var类型的实际类型,而以dynamic声明的变量却不支持”智能感知”,因为编译器对其运行期的类型一无所知.对dynamic变量使用”智能感知”,会提示”此操作将在运行时解析”.
关于dynamic变量是一个object变量这一点,可以通过IL代码得到验证.当然,编译器也对dynamic声明进行了处理,以区别直接object变量.
dynamic是作为简化互操作性而被MSDN大肆渲染,大部分开发人员有个误解:因为很多开发人员不会接触COM+,OFFICE二次开发之类的编码,所以急需要一个dynamic的应用理由.那么在开发中dynamic很有价值的一点是:
dynamic可以简化反射.
反射的内容还没介绍,我也还没学到哪里,学到了反射,我在和大家一起交流!!