特性是一种特殊的类。
要点:
声明:
public sealed class MyAttributeAttribute : System.Attribute
{
...
}
由于特性持有目标的信息,所有特性类的公有成员只能是:
构造函数的显式隐式声明定义,以及重载等等,规则跟其他类一样。
public MyAtrributeAttribute(string desc, string ver)
{
...
}
[MyAttribute("Holds a value")]//使用一个字符串的构造函数
public int MyField;
[MyAttribute("Version 1.3", "Galen Daniel")]//使用两个字符串的构造函数
public void MyMethod()
{
...
}
//MyAttribute:特性类
特性构造函数要点:
[MyAttr]
class SomeClass...
[MyAttr()]
class OtherClass...
//命令语句
MyClass mc = new MyClass("Hello", 5);
//声明语句
[MyAttribute("Holds a value")]
特性类和其他类,比较构造函数的使用:
[MyAttribute("An excellent class", Reviewer="Amy McArthur",Ver="0.7.15.33")]
//位置参数:An excellent class
//命名参数:Reviewer="Amy McArthur"、Ver="0.7.15.33"
示例:
public sealed class MyAttributeAttribute : System.Attribute
{
public string Description;
public string Ver;
public string Reviewer;
public MyAttributeAttribute(string desc)//一个形参
{
Description = desc;
}
}
[MyAtrribute("An excellent class", Reviewer="Amy McArthur", Ver="7.15.33")]
class MyClass
{
...
}
AttributeUsage 特性: 用来限制将特性用在某个目标类型上。
如果希望自定义特性 MyAttribute 只能应用到方法上。
[AttributeUsage(AttributeTarget.Method)]
public sealed class MyAtrributeAttribute : System.Attribute
{
...
}
表-AttributeUsage 的公有属性
名字 | 意义 | 默认值 |
---|---|---|
ValidOn | 保存能应用特性的目标类型的列表。构造函数的第一个参数必须是 AtrributeTargets 类型的枚举值 | |
Inherited | 一个布尔值,它指示特性是否可被装饰类型的派生类所继承 | true |
AllowMutiple | 一个布尔值,指示目标上是否可应用特性的多个实例的 | false |
AtrributeUsage 的构造函数接受单个位置参数,该参数指定了可使用特性的目标类型。它用这个参数来设置 ValidOn 属性,可接受的目标类型是 AttributeTargets 枚举的成员。
可用通过使用按位或运算符来组合使用类型。
[AttributeUsage(AttributeTarget.Method | AtrributeTarget.Constructor)]
public sealed class MyAttributeAttribute : System.Attribute
{
...
}
AttributeTargets 枚举的成员
– | – | – | – |
---|---|---|---|
All | Assembly | Class | Constructor |
Delegate | Enum | Event | Field |
GenericParameter | Interface | Method | Module |
Parameter | Property | ReterunValue | Struct |
[AttributeUsage(AttributeTarget.Class,
Inherited = false,
AllowMultiple = false
)]
public sealed class MyAttribute : System.Attribute
{
...
}
建议自定义特性时:
[AttributeUsage(AttributeTargets.Class)]
public sealed class ReviewCommentAtrribute : System.Attribute
{
public string Description {get; set;}
public string VersionNumber {get;set;}
public string ReviewrID {get;set;}
public ReviewCommentAtrribute(string desc,string ver)
{
Description = desc;
VersionNumber = ver;
}
}
使用 Type 对象来获取类型信息。Type 的两个方法:IsDefine 和 GetCustomAttributes。
1)使用 IsDefine 方法
可以使用 Type 对象 的 IsDefine 方法来检测某个特性是否应用到了某个类上。
[AttributeUsage(AttributeTargets.Class)]
public sealed class ReviewCommentAttribute : System.Attribute
{...}
[ReviewComent("Check ite out","2.4")]
class MyClass{ }
class Program
{
static void Main()
{
MyClass mc = new MyClass();
Type t = mc.GetType();
bool isDefined = t.IsDenfined(typeof(ReviewCommentAtrribute),false);
if(isDefined)
{
Console.WriteLine($"ReviewComment is applied to type { t.Name }");
}
}
}
输出结果:
ReviewComment is applied tp type MyClass
2)使用 GetCustomAttributes 方法
Type 类的 GetCustomAttributes 方法返回用用到结构上的特性的数组。
object[] AttArr = t.GetCustomAttributes(false);
[AttributeUsage(AttributeTargets.Class)]
public sealed class MyAtrributeAttribute : System.Attribute
{
public string Description { get; set; }
public string VersionNumber { get; set; }
public string ReviewerID { get; set; }
public MyAtrributeAttribute(string desc, string ver)
{
Description = desc;
VersionNumber = ver;
}
}
[MyAtrribute("Check it out","2.4")]
class MyClass
{ }
class Program
{
static void Main(string[] args)
{
Type t = typeof(MyClass);
object[] AttArr = t.GetCustomAttributes(false);
foreach(Attribute a in AttArr)
{
MyAtrributeAttribute attr = a as MyAtrributeAttribute;
if(null != attr)
{
Console.WriteLine($"Decription : { attr.Description }");
Console.WriteLine($"Version Number : { attr.VersionNumber }");
Console.WriteLine($"Reviewer ID : { attr.ReviewerID }");
}
}
Console.ReadKey();
}
}
输出结果:
Decription : Check it out
Version Number : 2.4
Reviewer ID :