轻松学C之运行时类型标识反射

上传人:宝路 文档编号:48718596 上传时间:2018-07-20 格式:PPTX 页数:31 大小:687.97KB
返回 下载 相关 举报
轻松学C之运行时类型标识反射_第1页
第1页 / 共31页
轻松学C之运行时类型标识反射_第2页
第2页 / 共31页
轻松学C之运行时类型标识反射_第3页
第3页 / 共31页
轻松学C之运行时类型标识反射_第4页
第4页 / 共31页
轻松学C之运行时类型标识反射_第5页
第5页 / 共31页
点击查看更多>>
资源描述

《轻松学C之运行时类型标识反射》由会员分享,可在线阅读,更多相关《轻松学C之运行时类型标识反射(31页珍藏版)》请在金锄头文库上搜索。

1、第15章 运行时类型标识、反射和特性运行时类型标识是一种在程序执行期间标识类 型的机制。反射功能可以为用户提供类型的信 息,从而使开发人员在运行时能够利用这些信 息构造和使用对象。特性则用于描述C#程序 中的元素的某种特性。特性同时使用了运行时 类型标识和反射。本章将详细介绍这3个相互 关联的功能。15.1 运行时类型标识运行时类型标识(RTTI)可以在程序执行期 间判定对象的类型。运行时类型标识还可以预 先测试某个强制类型转化操作能否成功,从而 避免无效的强制类型转换异常。运行时类型标 识是反射机制的关键组成部分。在C#中支持 运行时类型标识的关键字是is、as和typeof。15.1.1

2、IS运算符测试类型通过is运算符能够判断对象的类型是否为特定类型。换句话说 就是利用is运算符判断左右两边的类型是否相同或是兼容。is 运算符只返回布尔类型。它的通用形式如下图所示。这里测试expr表达式描述的对象是否为type指定的类型。如果 expr的类型与type指定的类型相同或兼容,那么结果为true, 否则为false。如果结果为true,expr表达式就能够转换为type 指定的类型。【示例15-1】以下使用is运算符判断类型是否相同。其中,由于b是B类型的对象,而B派生于A类型,因此b类型 与A类型兼容。反之,就不成立。因为a对象属于A类型,而A 类型不派生于B类型。所以a对象不

3、能转换为B类型。15.1.2 AS运算符一般我们都希望在程序运行期间执行转换,并且即使转换失 败也不会抛出异常。这样,就需要使用as运算符。as运算符的 通用形式如下图所示。其中,expr表达式将转换换为type指定的类型。如果转换成功 ,那么就返回一个type类型的引用,否则返回一个空引用。【示例15-2】以下代码利用as运算符避免无效的强制类型转 换。其中,as语句先检查强制转换是否有效,如果有效,则执行 强制转换过程。如果无效,则不执行强制转换。这样就不会 产生异常。这里,由于a和B类型不兼容,转化失败,所以对 象b为空引用。15.1.3 TYPEOF运算符typeof运算符可以返回与具

4、体类型相关的System.Type对象。 通过System.Type对象,可以确定此类型的特性。typeof运算 符的通用形式如下图所示。其中,type表示获得的类型,返回的Type对象封装了与type关 联的信息。【示例15-3】以下程序使用typeof运算符获取StreamReader类 型的Type对象的相关信息。其中,此程序调用了它的2个属性:FullName和IsClass。 FullName属性可以返回类型的全称,IsClass属性在类型为一 个类时返回真。15.2 反射反射是一种允许用户获得类型信息的C#功 能。它可以获取和使用只在运行时才能知道的 类型的功能。许多支持反射的类都

5、位于 System.Reflection命名空间中。因此,在使用 反射的程序中通常包含以下代码:using System.Reflection;15.2.1 SYSTEM.TYPESystem.Type类包装了类型,是整个反射子系统的核心。 System.Type类包含了很多属性和方法,使用这些属性和方法 可以在运行时得到类型的信息。Type类派生于 System.Reflection.MemberInfo抽象类。MemberInfo类定义的只 读属性如下表所示。属性功能Type DeclaringType获取声明该成员的类或接口的类型MemberTypes MemberType获取成员的类型

6、。这个值用于指示该成员是字段、方法、属性、事件 或构造函数int MetadataToken获取与特定元数据相关的值Module Module获取一个代表反射类型所在模块(可执行文件)的Module对象string Name成员的名称Type ReflectedType反射的对象的类型除了MemberInfo类定义的方法和属性,Type类还添加了许多 自己的方法和属性。如下表所示是Type类定义的常用方法。方法功能ConstuctInfoGetConstru ctors()获取指定类型的构造函数列表EventInfoGetEvents()获取指定类型的事件列表FieldInfoGetField

7、s()获取指定类型的字段列表TypeGetGenericArgume nts()获取与已构造的泛型类型绑定的类型实参列表,如果指定的类型是泛型类 型定义,则获 得类型形参。对于在在构造的类型,该列表就可能同时包含 类型实参和类型形参MemberInfoGetMembers ()获取指定类型的成员列表MethodInfoGetMethods( )获取指定类型的方法列表PropertyInfoGetProperti es()获取指定类型的属性列表Type类定义的只读属性如下表所示。属性功能Assembly Assembly获取指定类型的程序集TypeAttributes Attributes获取指

8、定类型的特性Type BaseType获取指定类型的直接基类型string FullName获取指定类型的全名bool IsAbstract如果指定类型是抽象类型,就返回truebool IsArray如果指定类型是数组,就返回truebool IsClass如果指定类型是类,就返回truebool IsEnum如果指定类型是枚举,就返回truebool IsGenericParameter如果指定类型是泛型类型参数,就返回truebool IsGenericType如果指定类型是泛型类型,就返回truestring Namespace取得指定类型的命名空间15.2.2 使用反射获取方法的相关

9、信息通过使用Type类定义的方法和属性,我们能够在运行时获得 类型的各种具体信息。一旦有了Type对象,就可以使用 GetMethods()方法获取此类型支持的方法的列表。该方法有以 下两种形式:1.GetMethods()方法的一种形式GetMethods()方法的一种形式为:MethodInfoGetMethods()它返回一个MethodInfo对象数组,MethodInfo对象描述了主调 类型所支持的方法,它位于System.Reflection命名空间中。 MethodInfo类派生于MethodBase抽象类,而MethodBase类继 承于MemberInfo类。此时,还有一个重

10、要成员GetParameters() 方法。GetParameters()方法返回一个方法的参数列表,它的通用形式 如下:ParameterInfoGetParameters()其中,参数信息保存在ParameterInfo对象中。ParameterInfo类 定义了大量描述参数信息的属性和方法。【示例15-4】使用反射获得Myclass类所支持的方法。对于每 个方法,它将显示该方法的名称、返回类型以及每个方法可 能具有的参数的名称和类型。注意:此程序中必须有以下代码:using System.Reflection;否则,会提示错误。2.GetMethods()方法的另一种形式在GetMeth

11、ods()方法的另一种形式中可以指定各种标记,以筛 选相应获取的方法。此形式值获得与指定的条件相匹配的方 法。其通用形式如下:MethodInfoGetMethods(BindingFlags bindingAttr)其中,BindingFlags是一个枚举。bindingAttr表示BindingFlags 枚举的值。下表是BindingFlags的一些常用值。值含义义DeclaredOnly仅获 取指定类定义的方法,而不获取类所继承的方法Instance获取实例方法NonPublic获取非公有方法Public获取公有方法Static获取static方法可以使用or运算符把两个或多个标记连接

12、在一起。一般,至 少应包含Instance或Static与Public或NonPublic标记,否则将不 会获取任何方法。【示例15-5】该程序使用GetMethods()方法的另一种形式重写 了前面的程序。15.2.3 使用反射调用方法如果知道了一个类型所支持的方法,那么就可以对方法进行 调用。在调用时,必须使用包含在MethodInfo类中的Invoke() 方法。其形式如下图所示。其中,obj是一个对象引用,将调用它所指向的对象上的方 法。对于static方法,obj必须为null。所有需要传递给方法的 参数都必须在parameters数组中指定。如果方法不需要参数, 则paramete

13、rs必须为null。另外,parameters数组的元素数量必 须等于参数数量。Invoke()方法返回被调用方法的返回值。【示例15-6】以下程序通过调用GetMethods()方法获得 MethodInfo实例,然后在MethodInfo实例上调用Invoke()方 法。其中,使用反射调用方法Invoke(),返回被调用方法的返回 值。15.2.4 使用反射获取TYPE对象的构造函数如果对象是在运行时动态创建的,使用反射的方式会有所不 同。首先需获取一个构造函数列表。然后,调用列表中的某 个构造函数,创建一个该类型的实例。通过这种机制,可以 在运行时实例化任意类型的对象,而不必再声明语句中

14、指定 类型。为了获得某个类型的公有非静态构造函数,需要调用Type对 象上的GetConstructors()方法。该方法的常用形式如下:ConstructorInfo GetConstructrs()其中,该方法返回一个描述构造函数的ConstructorInfo对象数 组。ConstructorInfo类派生于MethodBase抽象类,而MethodBase类 继承了MemberInfo类。ConstructorInfo类也定义了自己的一些 成员。其中主要的成员是GetParameters()方法,该方法可以返 回给定构造函数的参数列表,它的工作方式与在MethodInfo 类中定义的G

15、etParameters()方法相似。如果找到了合适的构造函数,就调用ConstructorInfo类定义的 Invoke()方法创建对象。该方法的形式如下:objet Invoke(object parameters)其中,需要传递给此方法的所有参数都在parameters数组中指 定。如果不需要任何参数,那么parameters必须为null。另外 ,parameters数组必须包含与参数数量相同的元素,并且实参 的类型必须与形参的类型兼容。Invoke()方法返回的是一个指 向新构造对象的引用。15.2.5 使用反射从程序集获得类型为了获得程序集的相关信息,首先需要创建一个Assembl

16、y对 象。Assembly类并没有定义公有的构造函数,它的对象实例 是通过调用类的一个方法获得的。使用LoadFrom()方法可以 加载由文件名指定的程序集,其形式如下图所示。其中,assemblyFile指定了程序集的文件名。如果获得了Assembly类型的对象,就可以通过在该对象上调 用GetTypes()方法得到它所定义的类型。该方法的通用形式如 下:Type GetTypes()其中,此方法返回一个数组,它包含了程序集中的类型。【示例15-7】该程序介绍了如何获取程序中的类型。其中,在编译“使用反射从程序集获得类型 示例”前应将 MyClass项目生成的MyClass.exe文件放到“使用反射从程序 集获得类型 示例使用反射从程序集获得类型 示例 binDebug”文件中。否则会产生如下图所示错误。15.3 特性C#允许开发人员以特性的形式为程序添加声 明性信息。特性定义了与类、结构

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 高等教育 > 大学课件

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号