定义/控制自定义属性的使用

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 ]

对应上述组合的结果:

    1. 如果我们查询(稍后我们会看见如何在运行时查询一个类的属性信息。)这个Derive类的Help属性时,会因其未从基类继承该属性而一无所获。
    2. 因为同样的原因,得到与结果一同样的结果。
    3. 为了解释这后面的两种情况,我们把同样的属性也用在这个Derive派生类上,代码修改如下:
[Help("BaseClass")] 
public class Base
{
}

[Help("DeriveClass")] 
public class Derive :  Base
{
}
  1. 我们的查询会同时得到其类Base与派生类Dervie的Help属性信息,因为继承与多重修饰均被允许。

注意:
  
AttributeUsage只能用于System.Attribute的派生类,且该派生类的AllowMultiple与Inherited都为false。

posted @ 2014-03-15 15:37  网络虫  阅读(329)  评论(0编辑  收藏  举报