在.Net4.0中引入了一个关键字dynamic,这是一个动态类型关键字。Net中还有一个关键字是var,这是一个隐式类型,可以定义本地变量,此时var所代表的实际的数据类型有编译器在初次分配时决定,比如:var a=1;a=“aa”;此时编译器就会报错,因为var在初次定义是已经被分配为int类型,它无法用于返回值、参数或者类/结构。这个时候就要想到所有类型的父类object,按照继承关系来说,object是所有类型的父类,所以它可以替代所有的类,也就是说:object a=1;a=“aa”;这样的表达式,编译器是可以编译通过的,但是因为它所指向的内存区域会因为类型的不同有所不同,所以为了可以正确访问我们所需要的类型的数据,我们在使用它的时候就需要进行显示转换,这样多少会影响性能,而且使用的时候还必须要非常注意,一不小心忘记显示转换就会报错。而dynamic更像是var与object的综合体,因为dynamic是不是强类型,所以它栽编译器初次定义类型之后,还可以根据重新分配的值的再次定义其类型,例如:dynamic a=1;a=“aa”;如果使用GetType()获取其类型名称,可知在给a赋值一个字符串之后,a的类型就变为string了。也因为dynamic在运行时代表任何类型(就像一个object类型的变量一样),那么就必然可以利用它调用属性,方法等成员。因为这是一个动态类型,直到运行时才会知道,所调用的动态变量是否支持指定的成员、所传递的参数是否正确已经成员名称的拼写是否有误,所以,这些数据是否出错,在编译的时候是无法得知的,智能在运行的时候才会知道是否有错误。同时在开发时vs也无法提供智能感知。因而,我们在使用dynamic所定义的变量是就需要非常小心才行,同时,我们还可以使用try...catch来使程序变得更加优雅。在dynamic出错时,抛出的错误通常是RuntimeBinderException类。

dynamic的作用域不仅在于可以用于变量,还可以用于参数、返回值、类/结构,但是dynamic不能使用Lambda表达式和C#匿名方法,以dynamic声明的变量不能用于LINQ to Object以及其他的LINQ技术。尽管dynamic有一些瑕疵,但是在一些场合,使用dynamic确实会给我们节省下很多的精力,比如在使用程序集通过反射进行的后期绑定时。比如,我们现在有一个CarLibrary程序集需要使用反射进行加载,使用其中的Minivan类的TurboBoost(int a,int b)方法,代码为:

Assembly asm=Assembly.Load("CarLibrary");//加载程序集

Type type=asm.GetType("CarLibrary.");//获取Minivan类型的元数据

object obj=Activator.CreateInstance(type);//创建Minivan类型

MethodInfo mi=math.GetMethod("TurboBoost");//获取方法的信息

object[] args={10,20};

mi.Invoke(obj,args);//调用方法

若是使用dynamic时,代码如下:

Assembly asm=Assembly.Load("CarLibrary");//加载程序集

Type type=asm.GetType("CarLibrary.");//获取Minivan类型的元数据

dynamic obj=Activator.CreateInstance(type);

obj.TurboBoost(10,20);

由上可见,使用dynamic的便利。

《精通C#》第十六章-动态类型和动态语言运行时-第一节至第四节的更多相关文章

  1. Gradle 1.12用户指南翻译——第三十六章. Sonar Runner 插件

    本文由CSDN博客万一博主翻译,其他章节的翻译请参见: http://blog.csdn.net/column/details/gradle-translation.html 翻译项目请关注Githu ...

  2. 20190902 On Java8 第十六章 代码校验

    第十六章 代码校验 你永远不能保证你的代码是正确的,你只能证明它是错的. 测试 测试覆盖率的幻觉 测试覆盖率,同样也称为代码覆盖率,度量代码的测试百分比.百分比越高,测试的覆盖率越大. 当分析一个未知 ...

  3. Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第十六章:实例化和截头锥体裁切

    原文:Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第十六章:实例化和截头锥体裁切 代码工程地址: https://git ...

  4. 鸟哥的linux私房菜——第十六章学习(程序管理与 SELinux 初探)

    第十六章.程序管理与 SE Linux 初探 在 Linux 系统当中:"触发任何一个事件时,系统都会将他定义成为一个程序,并且给予这个程序一个 ID ,称为 PID,同时依据启发这个程序的 ...

  5. Gradle 1.12 翻译——第十六章. 使用文件

    有关其它已翻译的章节请关注Github上的项目:https://github.com/msdx/gradledoc/tree/1.12,或訪问:http://gradledoc.qiniudn.com ...

  6. 第十六章——处理锁、阻塞和死锁(3)——使用SQLServer Profiler侦测死锁

    原文:第十六章--处理锁.阻塞和死锁(3)--使用SQLServer Profiler侦测死锁 前言: 作为DBA,可能经常会遇到有同事或者客户反映经常发生死锁,影响了系统的使用.此时,你需要尽快侦测 ...

  7. CSS3秘笈复习:十三章&十四章&十五章&十六章&十七章

    第十三章 1.在使用浮动时,源代码的顺序非常重要.浮动元素的HTML必须处在要包围它的元素的HTML之前. 2.清楚浮动: (1).在外围div的底部添加一个清除元素:clear属性可以防止元素包围浮 ...

  8. Gradle 1.12用户指南翻译——第二十六章. War 插件

    其他章节的翻译请参见: http://blog.csdn.net/column/details/gradle-translation.html 翻译项目请关注Github上的地址: https://g ...

  9. 《HTTP 权威指南》笔记:第十六章&第十七章 国际化、内容协商与转码

    <HTTP 权威指南>笔记:第十六章 国际化 客户端通过在请求报文中的 Accept-Language 首部和 Accept-Charset 首部来告知服务器:“我理解这些语言.”服务器通 ...

随机推荐

  1. c# winform vlcPlayer播放器

    vlcPlayer是一款免费开源的播放器项目,可以播放几乎所有的视频格式. 第一步:获取dll 安装vlcplayer视频播放器,在安装目录下面获取所需的dll. dll文件夹:plugins 还有2 ...

  2. Salesforce 执行顺序

    在服务器上,Salesforce按以下顺序执行: 1,从数据库加载原始记录或初始化一个用于更新插入(upsert)语句的记录. 2,从请求加载新记录的字段值并覆盖旧的值. 如果请求来自一个标准的UI( ...

  3. animate动画jquery

    <script> $(".change").animate({height:"hide",width:"300px"},&quo ...

  4. maven项目和普通项目转换

     

  5. 深入理解javascript原型和闭包(完结)

    原文链接:http://www.cnblogs.com/wangfupeng1988/p/3977924.html 说明: 该教程绕开了javascript的一些基本的语法知识,直接讲解javascr ...

  6. requirejs学习

  7. python之RabbitMQ

    一.安装RabbitMQ 1. 安装erlang 1 2 3 4 tar xf otp_src_18.3.tar.gz cd otp_src_18.3 ./configure --prefix=/ma ...

  8. linux开发摘要

    1.linux内核文档链接点击打开链接 2.配置文件 在out\target\product\project\obj\KERNEL_OBJ\.config中可以看到 # CONFIG_MTD_LPDD ...

  9. Android二维码功能实现,在程序内嵌入ZXing项目

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/9526247 最近二维码真是越来越火了,随便电视上.网络上.商场里,到处都是二维码. ...

  10. Executor框架(转载)

    Executor框架是指java 5中引入的一系列并发库中与executor相关的一些功能类,其中包括线程池,Executor,Executors,ExecutorService,Completion ...