WindowsDevCenter.com
oreilly.comSafari Books Online.Conferences.

advertisement


AddThis Social Bookmark Button O'Reilly Book Excerpts: VB .NET Language in a Nutshell

Attributes

by Steven Roman, Ron Petrusha, Paul Lomax

Defining a Custom Attribute

An attribute is merely a class that inherits from System.Attribute, which makes it very easy to implement a custom attribute. In this section, we'll build a custom attribute called <DeveloperNote>, which allows a developer to add assorted information (the developer's name, the date, a comment, and whether a code modification was a response to a bug) to code. The steps are as follows:

  1. Define a public class that inherits from System.Attribute or another attribute class derived from System.Attribute. For example:
  2. Public Class DeveloperNoteAttribute
     Inherits System.Attribute
    
  3. Note that, by convention, the name of the class ends with the substring "Attribute".
  4. Apply the <AttributeUsage> attribute, which defines the language elements to which the custom attribute can be applied, to the class (as shown in the following code fragment). The attribute's only required argument is one of the following members of the AttributeTargets enumeration:
  5. 
    All
    Assembly
    Class
    Constructor
    Delegate
    Enum
    Event
    Field
    Interface
    Method
    Module
    Parameter
    Property
    ReturnValue
    Struct
    
  6. If an attribute applies to multiple programming elements, but not all elements, the relevant constants can be ORed together. In the case of our <DeveloperNote> attribute, we want the attribute to apply to all program elements. In addition, we want to make the <DeveloperNote> attribute extensible through inheritance, so we set the <AttributeTarget> attribute's Inherited argument to True. Finally, we want to allow the application of multiple attributes to the same program element; hence, we want to set the AllowMultiple argument to True as well. In view of this setting, our code should look as follows:

  7. Related Reading

    VB.NET Language in a Nutshell
    By Steven Roman, Ron Petrusha, Paul Lomax

    
    <AttributeUsage(AttributeTargets.All, _
     Inherited:=True, _ 
     AllowMultiple:=True)> _
    Public Class DeveloperNoteAttribute
     Inherits System.Attribute
    
  8. Create the class constructor (the New subroutine), which is called when the attribute is applied to a particular language element. The class constructor defines the attribute's required or positional arguments. At a minimum, we'll want a developer to record his or her name, a comment, and the date. Our constructor appears as follows:
  9. 
    Public Sub New(Name As String, Comment As String, _
     DateRecorded As String)
     MyBase.New(  )
     strName = Name
     strComment = Comment
     datDate = CDate(DateRecorded)
    End Sub
    
  10. Note that the date is passed to the constructor as a String type. There is some restriction on the data types that can be used as attribute parameters. Parameters can be any integral data type (Byte, Short, Integer, Long) or floating point data type (Single and Double), as well as Char, String, Boolean, an enumerated type, or System.Type. Thus, Date, Decimal, Object, and structured types cannot be used as parameters.

    Each required parameter also corresponds to a class property or field. These parameters are added to the class in the next step.

  11. Declare properties or fields. The attribute's public properties and fields correspond both to parameters required by the class constructor and to optional parameters supplied when the attribute is applied to a language element. In the case of our attribute, we'll want properties that correspond to each attribute, as well as an additional Bugs property that indicates whether or not the comment corresponds to a code modification that resulted from a bug. The code is:
  12. 
    Public Property Name As String
       Get
          Return strName
       End Get
       Set
          strName = Value
       End Set
    End Property   
     
    Public Property Comment As String
       Get
          Return strComment
       End Get
       Set
          strComment = Value
       End Set
    End Property
     
    Public Property DateRecorded As Date
       Get
          Return datDate
       End Get
       Set
          datDate = Value
       End Set
    End Property
     
    Public Property Bug As Boolean
       Get
          Return blnBug
       End Get
       Set
          blnBug = Value
       End Set
    End Property
    

The complete code for the attribute class is shown in Example 8-1.

Example 8-1: The DeveloperNoteAttribute attribute class

Option Strict On
Imports System
 
Namespace Extensions.CustomAttributes
 
<AttributeUsage(AttributeTargets.All, _
                Inherited:=True, _ 
                AllowMultiple:=True)> _
Public Class DeveloperNoteAttribute
   Inherits System.Attribute
 
Protected strName, strComment As String
Protected blnBug As Boolean
Protected datDate As Date
 
Public Sub New(Name As String, Comment As String, DateRecorded As String)
   MyBase.New(  )
   strName = Name
   strComment = Comment
   datDate = CDate(DateRecorded)
End Sub
 
Public Property Name As String
   Get
      Return strName
   End Get
   Set
      strName = Value
   End Set
End Property   
 
Public Property Comment As String
   Get
      Return strComment
   End Get
   Set
      strComment = Value
   End Set
End Property
 
Public Property DateRecorded As Date
   Get
      Return datDate
   End Get
   Set
      datDate = Value
   End Set
End Property
 
Public Property Bug As Boolean
   Get
      Return blnBug
   End Get
   Set
      blnBug = Value
   End Set
End Property
 
End Class
 
End Namespace

In the last installment from this excerpt series, learn how to use custom attributes.