什么是特性
公共语言运行时使你能够添加类似于关键字的描述性声明(称为特性),以便批注编程元素(如类型、字段、方法和属性)。
编译运行时的代码时,它将被转换为 Microsoft 中间语言 (MSIL),并和编译器生成的元数据一起放置在可移植可执行 (PE) 文件内
自定义特性类
特性类是直接或间接派生自 Attribute 的类,下面定义一个叫Author的特性,AttributeUsage特性是对新特性的一限制。
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
public class Author : System.Attribute
{
private string name;
public double version;
public Author(string name)
{
this.name = name;
version = 1.0;
}
}
可按如下方式使用这一新特性:
[Author("P. Ackerman", version = 1.1)]
class SampleClass
{
// P. Ackerman's code goes here...
}
关于AttributeUsage
使用AttributeUsage,来控制如何应用新定义的特性,这非必要的。
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = true)]
AttributeTargets 成员
上述示例中指定了 AttributeTargets.All,它表示此特性可应用于所有程序元素。 或者,你可指定 AttributeTargets.Class 和 AttributeTargets.Method,前者表示你的特性仅可适用于一个类,后者表示你的特性仅可应用于一种方法
Inherited 属性
指明要对其应用属性的类的派生类能否继承此属性,默认可以继承
AllowMultiple 属性
指明元素能否包含属性的多个实例。一般一个特性一只会指定一次,默认false只能指定一次,但是如果AllowMultiple=true,通过此命名参数可一次或多次使用自定义特性。 下面的代码示例创建了一个多用特性。
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = true)]
public class Author : System.Attribute
在下面的代码示例中,某个类应用了同一类型的多个特性。
[Author("P. Ackerman", version = 1.1)]
[Author("R. Koch", version = 1.2)]
class SampleClass
{
// P. Ackerman's code goes here...
// R. Koch's code goes here...
}
特性的应用
下面实现读取枚举中文注释的特性,先定义一个Remark特性
public class RemarkAttribute : Attribute
{
public string Remark { get; private set; }
public RemarkAttribute(string remark)
{
this.Remark = remark;
}
}
为枚举扩展一个方法,用于使用特性,主要是通过反射得到传入枚举的特性的类,再得到这类的属性。
public static string GetRemark(this Enum value)
{
Type type = value.GetType();
var field = type.GetField(value.ToString());
if (field.IsDefined(typeof(RemarkAttribute), true))
{
RemarkAttribute attribute = (RemarkAttribute)field.GetCustomAttribute(typeof(RemarkAttribute), true);
return attribute.Remark;
}
else
{
return value.ToString();
}
}
可按如下方式使用这一新特性:
State state = State.Frozen;
string reamrk = state.GetRemark();//输出reamrk的值为:已冻结
总结
特性是要继承Attribute类,特性的使用主要都通过反射。