65.9K
CodeProject is changing. Read more.
Home

Expanding Enumerators for Saving to a Database or Displaying to a User

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.04/5 (9 votes)

Jan 26, 2006

2 min read

viewsIcon

37643

downloadIcon

170

An article showing how to use custom attributes with enumerators to display more information about the enumerator fields.

SmartEnumeratorAttribute

Introduction

When I'm developing an application, I often like to use enumerators as properties of my objects to improve the readability of my code. Often, the enumerator value will come from a table in the database. For example, we might have an enumerator resembling something like this:

Public Enum EmailStatus
    Unread
    Read
    Deleted
End Enum

Using enumerators is very useful when developing classes since it provides a strongly-typed way to implement business logic:

If Me.EmailStatus = EmailStatus.Read Then
    'do something
End If

Nevertheless, we're bound to run into a problem when we need to display the enumerator's value to the user. The same is true when we try to save the object's state to the database. Luckily, we can use a custom attribute to give us this type of functionality.

Background

This article will show you a basic implementation of how to use custom attributes in your enumerators. You can certainly expand the custom attribute to store more information about the field in the enumerator you wish to enhance.

Using the code

Creating a custom attribute is very much like creating any other class. The main difference is that we must inherit from System.Attribute.

Public Class SmartEnumeratorAttribute
    Inherits System.Attribute
End Class

Once we've done this, we must set the AttributeUsage of the class. Since we're only going to apply this to fields of an enumerator, the parameter should be set to AttributeTargets.Field. This tells the compiler that when using this attribute, it can only be applied to a field. We also don't want to allow the developer to apply this attribute to the same field multiple times, so we must set AllowMultiple = False.

<AttributeUsage(AttributeTargets.Field, AllowMultiple:=False)> _
Public Class SmartEnumeratorAttribute
    Inherits System.Attribute
End Class

At this point, we can begin to define the extended properties that we want a particular field of the enumerator to return. Since we want to be able to display the value to the user interface, we will create a Description property. We also want to save the enumerator's value to the database using a foreign key of type Integer. We will also be creating a public constructor that accepts the value of our properties to make the initialization of the attribute easier:

Private mDatabaseValue As String
Private mDescription As String

Public Property DatabaseValue() As String
    Get
        Return mDatabaseValue
    End Get
    Set(ByVal Value As String)
        mDatabaseValue = Value
    End Set
End Property

Public Property Description() As String
    Get
        Return mDescription
    End Get
    Set(ByVal Value As String)
        mDescription = Value
    End Set
End Property

Public Sub New(ByVal DatabaseValue As String, _
               ByVal Description As String)
    mDatabaseValue = DatabaseValue
    mDescription = Description
End Sub

Finally, to create the actual enumerator, just add the custom attribute to each field in the enumerator:

Public Enum EmailStatus
    <SmartEnumerator("1", "New E-mail")> Unread
    <SmartEnumerator("2", "Read E-mail")> Read
    <SmartEnumerator("3", "Deleted E-mail")> Deleted
End Enum

Accessing the custom attributes will involve the use of the System.Reflection namespace since the attribute is being applied to the individual fields of the enumerator:

Imports System
Imports System.Reflection
Imports System.ComponentModel

Public Class SmartEnum

    Public Shared Function GetDescription(ByVal _
                  obj As Object) As String

        Dim t As Type = obj.GetType

        Dim fInfo As FieldInfo = _
            t.GetField(System.Enum.GetName(t, obj))

        Dim attr As SmartEnumeratorAttribute = _
            DirectCast(fInfo.GetCustomAttributes(_
            GetType(SmartEnumeratorAttribute), _
            False)(0), SmartEnumeratorAttribute)

        Return attr.Description

    End Function
End Class

Points of Interest

Hopefully, this article has given you a better idea of how to use custom attributes with enumerators to increase the readability of your code when your enumerators need to interact with a database or display their value to the user.