定义/控制自定义属性的使用
AttributeUsage类是一个预定义的属性类,以帮助我们控制自定义属性的使用.也就是我们可以定义自定义属性类的属性.这个类描述了如何使用自定义的属性类.AttributeUsage有三个数据属性可用以修饰我们的自定义的属性.
ValidOn 定义了自定义属性在哪些程序实体上可被使用.这个可使用实体列表可通过 AttributeTargets枚举类型的OR操作进行设置
AllowMutiple 定义了是否可在同一个程序实体上同时使用多个属性进行修饰
Inherited 定义了自定义的修饰是否可由被修饰类的派生类继承
让我们做点具体的吧。我们将会用一个AttributeUsage属性修饰我们的属性类,以控制其作用范围:
using System; [AttributeUsage(AttributeTargets.Class), AllowMultiple = false, Inherited = false ] public class HelpAttribute : Attribute { public HelpAttribute(String Description_in) { this.description = Description_in; } protected String description; public String Description { get { return this.description; } } }
先看看AttributeTargets.Class,说明了我们的Help属性只能用以修饰类,下面的这段代码将会导致一个编译错误(“属性Help不能用在这样的声明上,它只能用在类的声明上”),因为我们用Help属性去修饰方法AnyMethod()了:
[Help("this is a do-nothing class")] public class AnyClass { [Help("this is a do-nothing method")] //error public void AnyMethod() { } }
编译错误:
AnyClass.cs: Attribute ''Help'' is not valid on this declaration type. It is valid on ''class'' declarations only.
当然我们可以AttributeTargets.All来允许Help属性修饰任何类型的程序实体。AttributeTargets可能的值包括:
- Assembly,
- Module,
- Class,
- Struct,
- Enum,
- Constructor,
- Method,
- Property,
- Field,
- Event,
- Interface,
- Parameter,
- Delegate,
- All = Assembly | Module | Class | Struct | Enum | Constructor | Method | Property | Field | Event | Interface | Parameter | Delegate,
- ClassMembers = Class | Struct | Enum | Constructor | Method | Property | Field | Event | Delegate | Interface )
接下来,该看看AllowMultiple = false这句了:它确定了不能象下面这样,在同一实体上同时使用多个同种属性进行修饰:
[Help("this is a do-nothing class")] [Help("it contains a do-nothing method")] public class AnyClass { [Help("this is a do-nothing method")] //这也是错误的,因为Help属性只能修饰类 public void AnyMethod() { } }
编译错误:
AnyClass.cs: Duplicate ''Help'' attribute
我们再来谈谈AttributeUsage的最后一个数据属性Inherited:定义了自定义属性的修饰是否可由被修饰类的派生类继承。基于下示代码表示的继承关系,让我们看看会发生什么吧:
[Help("BaseClass")] public class Base { } public class Derive : Base { }
我们选择了AttributeUsage的四种组合:
- [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false ]
- [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = false ]
- [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true ]
- [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true ]
对应上述组合的结果:
- 如果我们查询(稍后我们会看见如何在运行时查询一个类的属性信息。)这个Derive类的Help属性时,会因其未从基类继承该属性而一无所获。
- 因为同样的原因,得到与结果一同样的结果。
- 为了解释这后面的两种情况,我们把同样的属性也用在这个Derive派生类上,代码修改如下:
[Help("BaseClass")] public class Base { } [Help("DeriveClass")] public class Derive : Base { }
- 我们的查询会同时得到其类Base与派生类Dervie的Help属性信息,因为继承与多重修饰均被允许。
注意:
AttributeUsage只能用于System.Attribute的派生类,且该派生类的AllowMultiple与Inherited都为false。