另注:property和attribute的区别:

  • property是指类向外提供的数据区域,其中有get和set访问器来提供对数据的读写,即用于类中字段的存取;
  • attribute是描述对象在编译时或运行时属性的,有时也叫“特性”,用于标识类、方法等程序元素的附加性质。

一、AttributeUsageAtttribute属性的使用

定义您自己的属性 (Attribute) 类时,可通过在属性 (Attribute) 上放置 AttributeUsageAttribute 来控制属性 (Attribute) 类的使用方式。指示的属性 (Attribute) 类必须直接或间接地从 Attribute

通过定义以下参数设置 AttributeUsageAttribute

  • ValidOn(定位参数)

该定位参数指定可在其上放置所指示的属性 (Attribute) 的程序元素。AttributeTargets 枚举数中列出了可在其上放置属性 (Attribute) 的所有可能元素的集合。可通过按位“或”运算组合多个 AttributeTargets

   AttributeTargets枚举的可用元素:         

 成员名称说明

Assembly

可以对程序集应用属性。

Module

可以对模块应用属性。

Class

可以对类应用属性。

Struct

可以对结构应用属性,即值类型。

Enum

可以对枚举应用属性。

Constructor

可以对构造函数应用属性。

Method

可以对方法应用属性。

Property

可以对属性 (Property) 应用属性 (Attribute)。

Field

可以对字段应用属性。

Event

可以对事件应用属性。

Interface

可以对接口应用属性。

Parameter

可以对参数应用属性。

Delegate

可以对委托应用属性。

ReturnValue

可以对返回值应用属性。

GenericParameter

可以对泛型参数应用属性。

All

可以对任何应用程序元素应用属性。

                还可以传递 AttributeTargets 的多个实例。下列代码段指定自定义属性可应用到任何类或方法:

[AttributeUsage (AttributeTargets.Class | AttributeTargets.Method)]
  • AllowMultiple(命名参数)

          AllowMultiple属性指示元素中是否可存在属性的多个实例。如果设置为 true,则允许存在多个实例;如果设置为 false(默认值),则只允许存在一个实例。

  • Inherited(命名参数)

          该命名参数指定所指示的属性能否由派生类和重写成员继承。该属性采用 true(默认值)或 false 标志

 

 二、声明属性类

应用AttributeUsageAttribute后,可以开始定义属性细节。属性类的声明与传统类的声明类似,如下列代码所示:

 

 

public class MyAttribute : System.Attribute 
{
    // . . . 
}

此属性定义说明了下列几点:

  • 属性类必须声明为公共类。
  • 按照约定,属性类的名称以单词 Attribute 结尾。虽然并不要求这样,但出于可读性目的,建议采用此约定。应用属性时,可以选择是否包含 Attribute 一词。
  • 所有属性类都必须直接或间接地从 System.Attribute 继承。

三、声明构造函数

  • 用构造函数初始化属性的方法与对待传统类的方法相同;
  • 可重载该构造函数以适应值的不同组合,类的每个公共构造函数为该类定义一个有效的定位参数序列,命名参数则由属性 (Attribute) 类的非静态、公共和读写字段或属性 (Property) 定义
  • 如果同时为自定义属性类定义了属性,则在初始化属性时可使用命名参数和定位参数的组合。通常情况下,将所有必选参数定义为定位参数,将所有可选参数定义为命名参数。在这种情况下,如果没有必选参数,则无法初始化属性(在初始化属性类的一个对象--即为某一个程序元素指定属性--时,类的定位参数是必选的,只要按构造函数中的参数顺序给出其值即可,类的命名参数是可选的,需要以“参数名=值”的形式赋值,当然前提是参数可写,如实现该命名参数的属性具有set属性)

四、声明属性

  • 如果需要定义命名参数,或者要提供一种容易的方法来返回由属性存储的值,请声明属性。应将属性 (Attribute) 的属性 (Property) 声明为带有要返回的数据类型说明的公共实体。定义将保存属性值的变量,并将该变量与 get 方法和 set 方法关联。

五、自定义属性示例

  • 本节具体表现前面的信息,并显示如何设计一个简单的属性来记录有关代码段作者的信息。该示例中的属性存储程序员的名字和级别,和关于该代码是否已被复查过的信息。该示例使用三个私有变量存储要保存的实际值。每个变量用获取和设置这些值的公共属性表示。最后,用两个必选参数定义构造函数。
1 [AttributeUsage(AttributeTargets.All)]
 2 public class DeveloperAttribute : System.Attribute 
 3 {
 4         
 5     //Private fields.
 6     private string name;
 7     private string level;
 8     private bool reviewed;
 9 
10     //This constructor defines two required parameters: name and level.
11 
12     public  DeveloperAttribute(string name,string level)
13     {
14         this.name = name;
15         this.level = level; 
16         this.reviewed = false;
17     }
18 
19     //Define Name property.
20 //This is a read-only attribute.
21         
22     public virtual string Name
23     {
24         get {return name;}        
25     }
26 
27     //Define Level property.
28 //This is a read-only attribute.
29         
30     public virtual string Level
31     {
32         get {return level;}
33     }
34 
35     //Define Reviewed property. 
36 //This is a read/write attribute. 
37 
38     public virtual bool Reviewed
39     {
40         get {return reviewed;}
41     set {reviewed = value;}
42     }
43 }
  • 可通过下列方法之一,使用全名 DeveloperAttribute 或使用缩写名 Developer
1 [Developer("Joan Smith", "1")]
2 [Developer("Joan Smith", "1", Reviewed = true)]

         第一个示例显示只用必选命名参数应用的属性,而第二个示例显示同时使用必选参数和可选参数应用的属性。