定制特性(custom attribute)是.NET框架的一个创新构造。任何人都可以使用定制特性来定义一些信息,并将这些信息应用于所有的元数据上,然后在运行时通过查询这些可扩展的元数据信息来动态地改变代码的执行方式。
定制特性仅仅是为目标元素提供关联附加信息的一种方式。编译器的工作是将这些附加信息存放在托管模块的元数据中而已。大多数特性对于编译器没有任何的意义。编译器仅仅只是检测源代码中的定制特性,然后产生相应的元数据。
C#只允许将特性应用于定义了以下构造的源代码中:程序集、模块、类型、字段、方法、方法参数、方法返回值、属性,以及事件。
一个特性仅仅是一个类型的实例。要与CLS兼容,定制特性的类型必须直接或间接继承自System.Attribute。
可以在一个目标元素上应用多个不同的特性,当在一个目标元素上应用多个特性时,它们的顺序可以任意。
定义自己的特性
{
public FlagsAttribute()
{
}
}
FlagsAttribute继承自System.Attribute。所有的非抽象特性必须具有public访问限制,并且根据约定,所有的特性类型的名称都应该有一个Attribute后缀。最后,所有的非抽象特性都必须包含至少一个公有构造器。
给上面的特性加特性
public class FlagsAttribute : Attribute
{
public FlagsAttribute()
{
}
}
在定义的特性类型上应用了一个AttributeUsage实例,AttributeUsage特性告诉编译器自己定义的定制特性可以应用在那些地方,上例中,AttributeUsage特性表示Flags特性实例只可以应用于枚举类型上。
AttributeUsage另外一个属性是Inherited表示特性是否应该应用于派生类或派生方法上。
创建一个特性用来表示开发者的信息
[AttributeUsage(AttributeTargets.All)]
public class DeveloperAttribute : System.Attribute
{
// Private fields.
private string name;
private string level;
private bool reviewed;
// This constructor defines two required parameters: name and level.
public DeveloperAttribute( string name, string level)
{
this .name = name;
this .level = level;
this .reviewed = false ;
}
// Define Name property.
// This is a read-only attribute.
public virtual string Name
{
get { return name;}
}
// Define Level property.
// This is a read-only attribute.
public virtual string Level
{
get { return level;}
}
// Define Reviewed property.
// This is a read/write attribute.
public virtual bool Reviewed
{
get { return reviewed;}
set {reviewed = value;}
}
}
[Developer( " Alex He " , " 1 " ,Reviewed = true )]
class Program
{
public static string name = " 11111 " ;
static void Main( string [] args)
{
}
void MyMethod()
{
}
}
上例中Revieved不属于构造函数,叫做命名参数是一个可选参数
总结一下定义一个特性的步骤:
-
应用 AttributeUsageAttribute
-
声明属性类
-
声明构造函数
-
声明属性