创建特性
只要通过System.Attribute类进行派生,我们也可以创建出自己的特性。一般来说,如果除了包含和不包含特定的特性外,我们的代码不需要获得更多信息就可以完成需要的工作,那么我们就不必完成这些额外的工作。但有时,如果我们希望某些特性可以被自定义,则可以提供非默认的构造函数和/或可写属性。
另外,还需要为自己的特性做两个选择:要将其应用到什么类型的目标(类、属性或者是其他),以及是否可以对同一目标进行多次应用。要指定上述信息,我们需要通过对特性应用一个特性来实现(这句话实在是拗口!),这个特性就是AttributeUsageAttribute
。这个特性带有一个类型为AttributeTargets
的构造函数参数值,通过|
运算符即可通过相应的枚举值组合出我们需要的值。另外,该特性还有一个布尔值类型的属性AllowMultiple
,用于指定是否可以多次应用特性。
例如,下面的代码指定了一个特性可以应用到类或属性中(一次):
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false)]
class DoesInterestingThingsAttribute : Attribute
{
public DoesInterestingThingsAttribute(int howManyTimes)
{
HowManyTimes = howManyTimes;
}
public string WhatDoesItDo { get; set; }
public int HowManyTimes { get; private set; }
}
这样,就可以像前面的片段中看到的那样来使用DoesInterestingThings特性了:
[DoesInterestingThings(1000, WhatDoesItDo = "voodoo")]
public class DocoratedClass
{
}
只要像下面这样修改前面的代码,就可以访问这一特性的属性:
Type classType = typeof(DecoratedClass);
object[] customAttributes = classType.GetCustomAttributes(true);
foreach(object customAttribute in customAttributes)
{
Console.WriteLine("Attribute of type {0} found.", customAttribute);
DoesInterestingThingsAttribute interestingAttribute = customAttribute as DoesInterestingThingsAttribute;
if(interestingAttribute != null)
{
Console.WriteLine("This class does {0} x {1}!",
interestingAttribute.WhatDoesItDo,
interestingAttribute.HowManyTimes);
}
}
“特性”这一技术在所有.NET应用程序都可以变得非常有用,特别是WPF和Windows Store应用程序。本书其余的部分会多次涉及这一技术。