C#高级编程.第十三章反射.docVIP

  1. 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  4. 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  5. 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  6. 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  7. 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
第13章 反 射 反射是一个普通术语,描述了在运行过程中检查和处理程序元素的功能。例如,反射 允许完成以下任务: ● 枚举类型的成员 ● 实例化新对象 ● 执行对象的成员 ● 查找类型的信息 ● 查找程序集的信息 ● 检查应用于类型的定制特性 ● 创建和编译新程序集 这个列表列出了许多功能,包括.NET Framework 类库提供的一些最强大、最复杂的功 能。但本章不可能介绍反射的所有功能,仅讨论最常用的功能。 首先讨论定制特性,定制特性允许把定制的元数据与程序元素关联起来。这些元数据 是在编译过程中创建的,并嵌入到程序集中。接着就可以在运行期间使用反射的一些功能 检查这些元数据了。 在介绍了定制特性后,本章将探讨支持反射的一些基类,包括System.Type 和System. Reflection.Assembly 类,它们可以访问反射提供的许多功能。 为了演示定制特性和反射,我们将开发一个示例,说明公司如何定期升级软件,自动 解释升级的信息。在这个示例中,要定义几个定制特性,表示程序元素最后修改或创建的 日期,以及发生了什么变化。然后使用反射开发一个应用程序,在程序集中查找这些特性, 自动显示软件自某个给定日期以来升级的所有信息。 本章要讨论的另一个示例是一个应用程序,该程序读写数据库,并使用定制特性,把 类和特性标记为对应的数据库表和列。然后在运行期间从程序集中读取这些特性,使程序 可以自动从数据库的相应位置检索或写入数据,无需为每个表或列编写特定的逻辑。 第Ⅰ部分 C# 语言 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。编译器 还认为这个类包含控制特性用法的信息。特别是属性类需要指定: ● 特性可以应用到哪些程序元素上(类、结构、属性和方法等) ● 它是否可以多次应用到同一个程序元素上 ● 特性在应用到类或接口上时,是否由派生类和接口继承 322 第12 章反 射 ● 这个特性有哪些必选和可选参数 如果编译器找不到对应的特性类,或者找到一个这样的特性类,但使用特性的方式与 特性类中的信息不匹配,编译器就会产生一个编译错误。例如,如果特性类指定该特性只 能应用于字段,但我们把它应用到结构定义上,就会产生一个编译错误。 继续上面的示例,假定定义了一个FieldName 特性: [AttributeUsage(AttributeTargets.Property, AllowMultiple=false, Inherited=false)] public class FieldNameAttribute :

文档评论(0)

185****7617 + 关注
实名认证
文档贡献者

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

1亿VIP精品文档

相关文档