定制 attribute

       现在让我们来讨论Microsoft .Net最具创意的技术之一:定制attribute。相信很多人都用过,例如在使用很多.Net技术时(例如:Windows窗体、Web窗体、XML Web服务等等)。利用定制attribute,可以声明性地为自己的代码添加注解,从而实现一些特殊功能。定制attribute允许将定义的信息应用于几乎每一个元数据的记录项(如:类型TypeDef[类、结构、枚举、接口、委托],方法MethodDef[含构造器],参数ParamDef,字段FieldDef,属性PropertyDef,事件EventDef,AssemblyDef程序集,ModuleDef模块)。这种可扩展的元数据信息能在运行时查询,从而动态改变代码的执行方式。

       说了这么多,让我们来了解下定制attribute到底是什么。定制attribute实际是一个类的实例。为了符合CLS的要求,定制attribute类必须直接或间接地从公共抽象类System.Attribute派生。我们来看一个例子:

[DllImport("Kernel132",CharSet=CharSet.Auto,SetLastError=true)]

实际上,将一个attribute应用于一个目标元素时,语法类似于调用类的某个实例构造器。就像这里DllImport就有一个接受String类型参数的构造器,我们传了"Kernel132"。定制attribute类的构造器的参数称为“定位参数”。此外,允许设置与定制attribute类关联的公共字段或属性。定制attribute类有种特殊语法,允许定制attribute对象构造好之后,设置对象的任何公共字段或属性,就像这里DllImport的公共实例字段CharSet和SetLastError被分别设置为CharSet.Auto和true。

       关于定制attribute,应知道的是它们只是将一些附加信息与某个目标元素关联起来,编译器在托管模块的元数据中生成这些额外的元素。大多数定制attribute对编译器来说没有意义,编译器只是在源代码中检测定制attribute,并生成对应的元数据。在构造并初始化好定制attribute类对象之后,编译器会将这个attribute对象的状态序列化到目标元素的元数据表记录项中。所谓"定制attribute",就是一个类的实例,它被序列化成驻留在元数据中的一个字节流。在运行时,可以对元数据中包含的字节进行反序列化,从而构造类的一个实例。

       目前需要理解的是仅仅定义一个attribute类是没用的,将它们应用在一些目标元素上,除了在程序集中生成额外的元数据之外,没有任何意义。应用程序代码的行为不会有任何改变。所以我们要知道的是,定义定制attribute时,也必须实现一些代码来检测某些目标上是否存在该attribute类的实例,然后执行一些逻辑分支代码。正因为能做到这一点,定制attribute才如此有用。也就是说,定制attribute只是将它的信息序列化到了目标元素的元数据中,真正要改变目标元素的行为,需要靠调用目标元素处的代码来获取这些信息然后做出不同的行为。

所以我们需要在调用目标元素处的代码那里检测定制attribute,然后执行一些逻辑分支代码。

System.Attribute定义了三个静态方法来获取与一个目标关联的attribute(IsDefine、GetCustomAttributes、GetCustomAttribute------->p388)System.Reflection里定义了几个类允许你检查一个模块的元数据,这几个类还提供了类似的IsDefine、GetCustomAtrributes方法------->p389

检测定制attribute时不创建从Attribute派生的对象(使用System.Reflection.CustomAttributeData类------->p393)

最后我们来了解一下条件attribute类,我们先来看看如下代码:

//#define TEST

#define VERIFY

using System;

[Conditional("TEST")][Conditional("VERIFY")]

public sealed class CondAttribute:Attribute{...}

[Cond]

puclic class SomeClass{...}

如果一个attribute类应用了System.Diagnostics.ConditionalAttribute,就称为条件attribute类

编译器如果发现向目标元素应用了CondAttribute的一个实例,那么当含有目标元素的代码编译时,只有在定义TEST或VERIFY符号的前提下,编译器才会在元数据中生成attribute信息。

 

http://kb.cnblogs.com/page/87531/

http://blog.csdn.net/niwalker/article/month/2003/07

http://blog.csdn.net/FantasiaX/article/details/1627694

http://blog.csdn.net/FantasiaX/article/details/1636913

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值