C#高级编程七十天----dynamic类型

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可以简化反射.

反射的内容还没介绍,我也还没学到哪里,学到了反射,我在和大家一起交流!!

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-11-09 18:47:25

C#高级编程七十天----dynamic类型的相关文章

C#高级编程七十五天----C#使用指针

在C#中使用指针的语法 假设想在C#中使用指针,首先对项目进行过配置: 看到属性了吗?单击: 看到那个同意不安全代码了吗?选中 然后将有关指针,地址的操作放在unsafe语句块中.使用unsafekeyword是告诉编译器这里的代码是不安全的. unsafekeyword的使用: (1)放在函数前,修饰函数,说明在函数内部或函数的形參涉及到指针操作: unsafe static void FastCopy(byte[] src, byte[] dst, int count) { // Unsaf

重学《C#高级编程》(对象与类型)

昨天重看了下<C#高级编程>里面的对象与类型一章,发现自己有许多遗漏没懂的地方重新弄清楚明白了 先说说什么是对象吧,我个人的感觉是:在编程的世界里,一段程序就是一个事物的处理逻辑,而对象就是针对这个逻辑的一个个抽象概念. 比方:我们要写程序实现“一个人喝水”,按照我的习惯,这里可以拆分出两个对象 1,“人”对象:这个人可以是张三,李四,甚至可以是一只动物 2,“水”对象:这个水也是一个概念化的东西,冰水,白水,酒,饮料都行 一个类就是一个对象,一个类可以有数据成员和函数成员,数据成员包括:字段

【读书笔记】C#高级编程 第十二章 动态语言扩展

(一)DLR C#4的动态功能是Dynamic Language Runtime(动态语言运行时,DLR)的一部分.DLR是添加到CLR的一系列服务. (二)dynamic类型 dynamic类型允许编写忽略编译期间的类型检查的代码.编译器假定,给dynamic类型的对象定义的任何操作都是有效的,在运行之前编译器不会检测是否存在错误. 例子: dynamic person = "人"; string firstName = person.FirstName; 这两行代码能够通过编译器编

C++面向对象高级编程(七)point-like classes和function-like classes

技术在于交流.沟通,转载请注明出处并保持作品的完整性. 1.pointer-like class 类设计成指针那样,可以当做指针来用,指针有两个常用操作符(*和->),所以我们必须重载这两个操作 /*简单实现一下智能指针的*与 -> 操作符*/ template <class T> class shared_ptr_test { public: T& operator* () const //重载* { return *px; } T* operator->() co

C#高级编程六十九天----DLR简介

DLR 一.近年来,在TIOBE公司每个月发布的编程语言排行榜中,C#总是能挤进前十名,而在最近十年来,C#总体上呈现上升的趋势.C#能取得这样的成绩,有很多因素,其中它在语言特性上的锐意进取让人印象深刻. C#4动态功能是Dynamic Language Runtime(动态语言运行时,DLR)的一部分.DLR是添加到CLR的一系列服务,它允许添加动态语言,如Ruby和Python,并使C#具备和这些动态语言相同的某些功能. 动态编程语言并非什么新鲜事物,早在面向对象编程语言成为主流之前,人们

C#高级编程五十四天----Lookup类和有序字典

Lookup类 Dictionary<Tkey,TValue>只为每个键支持一个值.新类Lookup<Tkey,TValue>是.NET3.5中新增的,它类似与Dictionary<Tkey,TElement>,但把键映射带一个值集上.这个类在程序及System.Core中实现,用System,Linq命名空间定义. Lookup<Tkey,TElement>的方法和属性如下表: 属性名或者方法名 说明 Count 属性Count返回集合中的元素个数 Ite

【读书笔记】C#高级编程 第二十四章 文件和注册表操作

(一)文件和注册表 对于文件系统操作,相关的类几乎都在System.IO名称空间中,而注册表操作由System.Win32名称空间中的类来处理. (二)管理文件系统 System.MarshalByRefObject--这是.NET类中用于远程操作的基对象类,它允许在应用程序域之间编组数据. FileSystemInfo--这是表示任何文件系统对象的基类. FileInfo和File--这些类表示文件系统上的文件. DirectoryInfo和Directory--这些类表示文件系统上的文件夹.

【读书笔记】C#高级编程 第二十二章 安全性

(一)身份验证和授权 安全性的两个基本支柱是身份验证和授权.身份验证是标识用户的过程,授权在验证了所标识用户是否可以访问特性资源之后进行的. 1.标识和Principal 使用标识可以验证运行应用程序的用户.Principal是一个包含用户的标识和用户所属角色的对象. AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal); var principal = WindowsPrincipal.Curr

C#高级编程七十二天----DynamicObject和ExpandoObject

DynamicObject和ExpandoObject 1.ExpandoObject表示一个对象,该对象包含可在运行时动态添加和移除的成员.这个类和动态类型有关,这个类能做些什么? 案例: //ExpandoObject这个类需要引入System.Dynamic; dynamic dynEO = new ExpandoObject(); dynEO.number = 20; dynEO.Method = new Func<int, string>((int i) => { return