如示例4.1所示,ICustomAttributeProvider接口支持两个用于发现特性的方法:ISDefined和GetCustomAttribute, IsDefined方法接收System.Type对象,它用来描述你所查询的特性,并且返回一个布尔值以标明该成员是否有指定类型的特性。Inherited参数控制应用到基类型上的特性是否在考虑之列.IsDefined方法的开销相对较低,原因是不需要初始化新的对象来确定特性的存在。它所返回的只是简单的是或者不是。
示例4.2展示了IsDefinecd方法的运用。该示例检测类型的每个方法,判断是应用了TestedAttribute特性,还是DocumentedAttribute特性。对于这些简单特性,IsDefined就能够胜任,因为我们关心的只是特性的存在与否。
自定义特性还能接收参数作为其声明的部分。特性类型的公有构造函数方法规定了允许的参数类型和数量,例如,考虑TestedAttribute类型的更新版本:
Public sealed class TestedAttribute:System.Attribute
{
Public TestedAttribute(){}
Public TestedAttribute(string tester){}
Public TestedAttrubite(string tester,double confidence){}
}
对于这个给定的新版本,你可以像下面这样使用自定义特性
Public sealed clas MyCode
{
[Tested]
Static void f(){}
[Tested(“Don Box”)]
Static void g(){}
[Tested(“Chris Sells”,100)]
Static void h(){}
}
允许使用这些参数的原因是该特性类型有相应的构造函数方法,CLR限制特性参数的类型为基本类型、字符串和System.Type引用。
前面示例所展示的自定义特性参数是基于构造函数的签名按位置传递的。此外,按名字传递参数到一个自定义特性也是合法的。按名字传递特性参数需要底层特性类型具有公共属性或字段,其名字匹配参数所指定的名字。考虑前面定义的DocumentedAttrubute类型的更新版本:
Public sealed class DocumentedAttrubute:System.Attribute
{
Public DocumentedAttribute(){}
Public DocumentedAttrubute(string w){Writer=w;}
Publicstring Writer;
Public int WordCount;
Public bool Reviewed;
}
该特性可以按下面的方式使用
Public sealed class MyCode
{
[Documented(“Don Box”,WordCount=42)]
Static void f(){}
[Documented(WordCount=42,Reviewed=false)]
Static void g(){}
[Documented(“Don Box”, Reviewed =true)]
Static void h(){}
}
这里之所以允许将位置型参数应用到f方法上,是因为该特件类型有一个兼容的构造函数方法,它能接收一个单独的字符串参数。此外,允许命名参数的原因是该特性有相同名字的公有字段或属性。v瀃皊v^ g\鶺,g{|媁
T饄(