要设计自己的自定义属性,不必掌握许多新的概念。如果熟悉面向对象的编程,并且知道如何设计类,就已具备了所需的大部分知识。自定义属性本质上是直接或间接地从 System.Attribute [ http://msdn2.microsoft.com/zh-cn/library/system.attribute.aspx ] 派生的传统类。与传统类一样,自定义属性也包含存储和检索数据的方法。
正确设计自定义属性类的主要步骤如下:
本节描述上述每个步骤,并以自定义属性示例结束。
应用 AttributeUsageAttribute
<AttributeUsage(AttributeTargets.All, Inherited := False, AllowMultiple := true)>
System.AttributeUsageAttribute 类 [ http://msdn2.microsoft.com/zh-cn/library/system.attributeusageattribute.aspx ] 包含三个对自定义属性的创建具有重要意义的成员:AttributeTargets、Inherited 和 AllowMultiple。
AttributeTargets 成员
[AttributeUsage (AttributeTargets.Class | AttributeTargets.Method)]
<AttributeUsage (AttributeTargets.Class Or AttributeTargets.Method)>
继承属性
//This defaults to Inherited = true. public class MyAttribute :Attribute { }
[AttributeUsage( Inherited = false)] public class YourAttribute : Attribute { }
<AttributeUsage( AttributeTargets.All, Inherited := True)> Public Class _ MyAttribute Inherits Attribute End Class <AttributeUsage( AttributeTargets.All, Inherited := False)> Public Class _ YourAttribute Inherits Attribute End Class
然后,这两个属性应用到基类 MyClass 中的某个方法。
public class MyClass { [MyAttribute] [YourAttribute] public virtual void MyMethod() { //... } }
' In Microsoft Visual Basic, you apply multiple attributes ' by separating them with commas. Public Class [MyClass] <MyAttribute, YourAttribute> Public Overridable Sub MyMethod() '... End Sub End Class
最后,YourClass 类从基类 MyClass 继承。方法 MyMethod 显示 MyAttribute,而不是 YourAttribute。
public class YourClass: MyClass { //MyMethod will have MyAttribute but not YourAttribute. public override void MyMethod() { //... } }
Public Class YourClass Inherits [MyClass] 'MyMethod will have MyAttribute but not YourAttribute. Public overrides Sub MyMethod() '... End Sub End Class
AllowMultiple 属性
//This defaults to AllowMultiple = false. public class MyAttribute :Attribute { } [AttributeUsage(AllowMultiple = true)] public class YourAttribute : Attribute { }
'This defaults to AllowMultiple = false. <AttributeUsage(AttributeTargets.Method)> Public Class _ MyAttribute Inherits Attribute End Class <AttributeUsage(AttributeTargets.Method, AllowMultiple := True)> Public Class _ YourAttribute Inherits Attribute End Class
当应用这些属性的多个实例时,MyAttribute 将生成编译器错误。下面的代码示例显示 YourAttribute 的有效用法和 MyAttribute 的无效用法。
public class MyClass { //This produces an error. //Duplicates are not allowed. [MyAttribute] [MyAttribute] public void MyMethod() { //... } //This is valid. [YourAttribute] [YourAttribute] public void YourMethod(){ //... } }
' In Microsoft Visual Basic you apply multiple attributes ' by separating them with commas. Public Class [MyClass] 'This produces an error. 'Duplicates are not allowed. <MyAttribute, MyAttribute> Public Overridable Sub MyMethod() '... End Sub 'This is valid. <YourAttribute, YourAttribute> Public Sub YourMethod() '... End Sub End Class
如果 AllowMultiple 属性和 Inherited [ http://msdn2.microsoft.com/zh-cn/library/system.attributeusageattribute_properties.aspx ] 属性都设置为 true,则从另一个类继承的类可以继承一个属性,并在同一子类中应用同一属性的另一个实例。如果 AllowMultiple 设置为 false,则父类中的所有属性值将被子类中同一属性的新实例重写。
AllowMultiple [ http://msdn2.microsoft.com/zh-cn/library/system.attributeusageattribute_properties.aspx ] 属性指示元素中是否可存在属性的多个实例。如果设置为 true,则允许存在多个实例;如果设置为 false(默认值),则只允许存在一个实例。 Inherited [ http://msdn2.microsoft.com/zh-cn/library/system.attributeusageattribute_properties.aspx ] 属性指示属性是否可由从该属性应用到的类派生的类继承。该属性采用 true(默认值)或 false 标志。例如,在下面的代码示例中, MyAttribute 的默认 Inherited 值为 true,而 YourAttribute 的 Inherited 值为 false。 AttributeTargets [ http://msdn2.microsoft.com/zh-cn/library/system.attributetargets.aspx ] 的多个实例。下列代码段指定自定义属性可应用到任何类或方法。声明属性类
public class MyAttribute : System.Attribute { // . . . }
' This attribute is only usable with methods <AttributeUsage(AttributeTargets.Method)> Public Class MyAttribute Inherits System.Attribute ' . . . End Class
此属性定义说明了下列几点:
-
属性类必须声明为公共类。
-
按照约定,属性类的名称以单词 Attribute 结尾。虽然并不要求这样,但出于可读性目的,建议采用此约定。应用属性时,可以选择是否包含 Attribute 一词。
-
所有属性类都必须直接或间接地从 System.Attribute 继承。
-
在 Microsoft Visual Basic 中,所有自定义属性类都必须具有 AttributeUsageAttribute 属性。
声明构造函数
Public Sub New(newvalue As Boolean) Me.myvalue = newvalue End Sub
可重载该构造函数以适应值的不同组合。如果同时为自定义属性类定义了属性 [ http://msdn2.microsoft.com/zh-cn/library/65zdfbdt.aspx ] ,则在初始化属性时可使用命名参数和定位参数的组合。通常情况下,将所有必选参数定义为定位参数,将所有可选参数定义为命名参数。在这种情况下,如果没有必选参数,则无法初始化属性。其他所有参数都是可选参数。请注意,在 Visual Basic 中,属性类的构造函数不应使用 ParamArray 参数。
下面的代码示例显示如何使用可选参数和必选参数应用使用上例中的构造函数的属性。它假定该属性有一个必选布尔值和一个可选字符串属性。
//One required (positional) and one optional (named) parameter are applied. [MyAttribute(false, OptionalParameter = "optional data")] //One required (positional) parameter is applied. [MyAttribute(false)]
'One required (positional) and one optional (named) parameter are applied. <MyAttribute(False, OptionalParameter := "optional data")> ' ... 'One required (positional) parameter is applied. <MyAttribute(False)>
声明属性
public bool MyProperty { get {return this.myvalue;} set {this.myvalue = value;} }
Public Property MyProperty As Boolean Get Return Me.myvalue End Get Set Me.myvalue = value End Set End Property
自定义属性示例
<AttributeUsage(AttributeTargets.All)> Public Class DeveloperAttribute Inherits System.Attribute 'Private fields. Private m_name As String Private m_level As String Private m_reviewed As Boolean 'This constructor defines two required parameters: name and level. Public Sub New(name As String, level As String) Me.m_name = name Me.m_level = level Me.m_reviewed = False End Sub 'Define Name property. 'This is a read-only attribute. Public Overridable ReadOnly Property Name() As String Get Return m_name End Get End Property 'Define Level property. 'This is a read-only attribute. Public Overridable ReadOnly Property Level() As String Get Return m_level End Get End Property 'Define Reviewed property. 'This is a read/write attribute. Public Overridable Property Reviewed() As Boolean Get Return m_reviewed End Get Set m_reviewed = value End Set End Property End Class
可通过下列方法之一,使用全名 DeveloperAttribute 或使用缩写名 Developer 来应用该属性。
[Developer("Joan Smith", "1")]
[Developer("Joan Smith", "1", Reviewed = true)]
<Developer("Joan Smith", "1")> <Developer("Joan Smith", "1", Reviewed := True)>
第一个示例显示只用必选命名参数应用的属性,而第二个示例显示同时使用必选参数和可选参数应用的属性。


