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

在.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的便利。

时间: 2024-11-07 05:54:23

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

C Primer Plus (第五版) 第十六章 C预处理器和C库 编程练习

第十六章 C预处理器和C库 开发一个包含您需要使用的预处理器定义的头文件 //max.h  #ifndef _MAX_H_     #define _MAX_H_     #define MAX(X, Y) ((X)>(Y)?(X):(Y)) #endif 2.两个数的调和平均数可用如下方法得到:首先对两数的倒数取平均值,最后再取倒数.使用#define指令定义一个宏"函数"执行这个运算.编写一个简单的程序测试该宏. #include <stdio.h> #defin

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

本文由CSDN博客万一博主翻译,其他章节的翻译请参见: http://blog.csdn.net/column/details/gradle-translation.html 翻译项目请关注Github上的地址: https://github.com/msdx/gradledoc/tree/1.12. 直接浏览双语版的文档请访问: http://gradledoc.qiniudn.com/1.12/userguide/userguide.html. 另外,Android 手机用户可通过我写的一个

【.NET Core项目实战-统一认证平台】第十六章 网关篇-Ocelot集成RPC服务

原文:[.NET Core项目实战-统一认证平台]第十六章 网关篇-Ocelot集成RPC服务 [.NET Core项目实战-统一认证平台]开篇及目录索引 一.什么是RPC RPC是"远程调用(Remote Procedure Call)"的一个名称的缩写,并不是任何规范化的协议,也不是大众都认知的协议标准,我们更多时候使用时都是创建的自定义化(例如Socket,Netty)的消息方式进行调用,相比http协议,我们省掉了不少http中无用的消息内容.因此很多系统内部调用仍然采用自定义

20190902 On Java8 第十六章 代码校验

第十六章 代码校验 你永远不能保证你的代码是正确的,你只能证明它是错的. 测试 测试覆盖率的幻觉 测试覆盖率,同样也称为代码覆盖率,度量代码的测试百分比.百分比越高,测试的覆盖率越大. 当分析一个未知的代码库时,测试覆盖率作为一个粗略的度量是有用的.如果覆盖率工具报告的值特别低(比如,少于百分之40),则说明覆盖不够充分.然而,一个非常高的值也同样值得怀疑,这表明对编程领域了解不足的人迫使团队做出了武断的决定.覆盖工具的最佳用途是发现代码库中未测试的部分.但是,不要依赖覆盖率来得到测试质量的任何

CSS3秘笈复习:十三章&amp;十四章&amp;十五章&amp;十六章&amp;十七章

第十三章 1.在使用浮动时,源代码的顺序非常重要.浮动元素的HTML必须处在要包围它的元素的HTML之前. 2.清楚浮动: (1).在外围div的底部添加一个清除元素:clear属性可以防止元素包围浮动元素.关键字:left.right或both. (2).浮动外围元素:让包含浮动元素的<div>也浮动.选择这种方法一定要在浮动容器后面的任何元素中添加一个clear属性,确保浮动元素落到容器的下方. (3).利用overflow : hidden.另一种常见的方法是在外围的样式中添加以下属性:

第十六章 多态性

相同函数名具有多态性: ①  译时的多态(由函数名来调用时体现):重载:同类,不同参 ②  运行时的多态(用指向不同类的指针来调用): 覆盖:  不同类,同参,基类有virtual(由指针的类型来决定,体现了多态性) 隐藏:①不同类,同参,基类无virtual②不同类,不同参(不论有无virtual)(由指针来决定,不能体现多态性) 1.  为什么要使用多重继承 多态性可以简单地概括为“一个接口,多种方法”,程序在运行时才决定调用的函数.C++多态性是通过虚函数(virtual)来实现的. 2.

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

有关其他已翻译的章节请关注Github上的项目:https://github.com/msdx/gradledoc/tree/1.12,或访问:http://gradledoc.qiniudn.com/1.12/userguide/userguide.html 本文原创,转载请注明出处:http://blog.csdn.net/maosidiaoxian/article/details/41113353 关于我对Gradle的翻译,以Github上的项目及http://gradledoc.qin

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

原文:第十六章--处理锁.阻塞和死锁(3)--使用SQLServer Profiler侦测死锁 前言: 作为DBA,可能经常会遇到有同事或者客户反映经常发生死锁,影响了系统的使用.此时,你需要尽快侦测和处理这类问题. 死锁是当两个或者以上的事务互相阻塞引起的.在这种情况下两个事务会无限期地等待对方释放资源以便操作.下面是死锁的示意图: 本文将使用SQLServer Profiler来跟踪死锁. 准备工作: 为了侦测死锁,我们需要先模拟死锁.本例将使用两个不同的会话创建两个事务. 步骤: 1. 打

第十六章——处理锁、阻塞和死锁(1)——确定长时间运行的事务

原文:第十六章--处理锁.阻塞和死锁(1)--确定长时间运行的事务 前言: 事务是OLTP系统中的主要部分.它管理数据一致性和数据并发问题,当多个资源同时被读取或者修改相同数据时,SQLServer会通过锁定机制来确保数据库中的数据总是处于一个有效状态.在SQLServer中,锁管理器是负责实现这些锁机制.SQLServer对于不同的资源类型提供不同的锁类型,如数据库.文件.对象.表.区.页和键. 当你使用事务时,依然会遇到由事务引起的问题,这些通常是由于锁.阻塞和死锁引起的. 本系列将讲解这三