第13节 反射.doc

  1. 1、本文档共16页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
第13章 反 射 2 13.1 定制特性 2 13.1.1 编写定制特性 2 13.1.2 定制特性示例:WhatsNewAttributes 5 13.2 反射 8 13.2.1 System.Type 类 8 13.2.2 TypeView 示例 10 13.2.3 Assembly 类 11 13.2.4 完成WhatsNewAttributes 示例 13 13.3 小结 16 第13章 反 射 反射是一个普通术语,描述了在运行过程中检查和处理程序元素的功能。例如,反射允许完成以下任务: ● 枚举类型的成员 ● 实例化新对象 ● 执行对象的成员 ● 查找类型的信息 ● 查找程序集的信息 ● 检查应用于类型的定制特性 ● 创建和编译新程序集 这个列表列出了许多功能,包括.NET Framework 类库提供的一些最强大、最复杂的功能。但本章不可能介绍反射的所有功能,仅讨论最常用的功能。 首先讨论定制特性,定制特性允许把定制的元数据与程序元素关联起来。这些元数据是在编译过程中创建的,并嵌入到程序集中。接着就可以在运行期间使用反射的一些功能检查这些元数据了。 在介绍了定制特性后,本章将探讨支持反射的一些基类,包括System.Type 和System.Reflection.Assembly 类,它们可以访问反射提供的许多功能。 为了演示定制特性和反射,我们将开发一个示例,说明公司如何定期升级软件,自动解释升级的信息。在这个示例中,要定义几个定制特性,表示程序元素最后修改或创建的日期,以及发生了什么变化。然后使用反射开发一个应用程序,在程序集中查找这些特性,自动显示软件自某个给定日期以来升级的所有信息。 本章要讨论的另一个示例是一个应用程序,该程序读写数据库,并使用定制特性,把类和特性标记为对应的数据库表和列。然后在运行期间从程序集中读取这些特性,使程序可以自动从数据库的相应位置检索或写入数据,无需为每个表或列编写特定的逻辑。 13.1 定制特性 前面介绍了如何在程序的各个数据项上定义特性。这些特性都是Microsoft 定义好的,作为.NET Framework 类库的一部分,许多特性都得到了C#编译器的支持。对于这些特性,编译器可以以特殊的方式定制编译过程,例如,可以根据StructLayout 特性中的信息在内存中布置结构。 .NET Framework 也允许用户定义自己的特性。显然,这些特性不会影响编译过程,因为编译器不能识别它们,但这些特性在应用于程序元素时,可以在编译好的程序集中用作元数据。这些元数据在文档说明中非常有用。但是,使定制特性非常强大的因素是使用反射,代码可以读取这些元数据,使用它们在运行期间作出决策,也就是说,定制特性可以直接影响代码运行的方式。例如,定制特性可以用于支持对定制许可类进行声明代码访问安全检查,把信息与程序元素关联起来,由测试工具使用,或者在开发可扩展的架构时,允许加载插件或模块。 13.1.1 编写定制特性 为了理解编写定制特性的方式,应了解一下在编译器遇到代码中某个应用了定制特性的元素时,该如何处理。以数据库为例,假定有一个C#属性声明,如下所示。 [FieldName(SocialSecurityNumber)] public string SocialSecurityNumber { get { // etc. 当C#编译器发现这个属性有一个特性FieldName 时,首先会把字符串Attribute 添加到这个名称的后面,形成一个组合名称FieldNameAttribute,然后在其搜索路径的所有命名空间(即在using 语句中提及的命名空间)中搜索有指定名称的类。但要注意,如果用一个特性标记数据项,而该特性的名称以字符串Attribute 结尾,编译器就不会把该字符串加到组合名称中,而是不修改该特性名。因此,上面的代码实际上等价于: [FieldNameAttribute(SocialSecurityNumber)] public string SocialSecurityNumber { get { // etc. 编译器会找到含有该名称的类,且这个类直接或间接派生自System.Attribute。编译器还认为这个类包含控制特性用法的信息。特别是属性类需要指定: ● 特性可以应用到哪些程序元素上(类、结构、属性和方法等) ● 它是否可以多次应用到同一个程序元素上 ● 特性在应用到类或接口上时,是否由派生类和接口继承 ● 这个特性有哪些必选和可选参数 如果编译器找不到对应的特性类,或者找到一个这样的特性类,但使用特性的方式与特性类中的信息不匹配,编译器就会产生一个编译错误。例如,如果特性类指定该特性只能应用于字段,但我们把它应用到结构定义上,就会产生一个编译错误。

文档评论(0)

189****6140 + 关注
实名认证
内容提供者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档