Click here to Skip to main content
Click here to Skip to main content

String Enumerations in VB.NET

, 4 May 2009 BSD
Rate this:
Please Sign up or sign in to vote.
Fully compatible enumeration using strings in VB.NET.

Introduction

This class allows strings to be used as enumerations. It is fully compatible with strings, including easy casting to a string, upcasting from strings, concatenation, and compatible with strings using the = operator. Developers will be able to code against this class as if it were a normal enumeration - without any special handling required.

This StringEnumeration class allows you to bridge any real-world string constants with an acceptable .NET enumeration you can use throughout your code.

Scenarios for using this class - When an enumeration must contain:

  • Global Unique Identifiers (GUIDs)
  • Strings that include spaces
  • Strings with special characters or that begin with a number
  • Scalar/Mixed types (strings, numbers, etc.)

Background

.NET enumerations do not support strings out-of-the-box. This class fixes this limitation.

Using the Code

Creating a String Enumeration

Using the class is very simple, just inherit from StringEnumeration and call its constructor. Here is an example:

Public NotInheritable Class ProductType
    Inherits StringEnumeration(of ProductType)

    Public Shared ReadOnly FifthWheels As New ProductType("Fifth Wheels")
    Public Shared ReadOnly MotorHomes As New ProductType("Motor Homes")
    Public Shared ReadOnly TentCampers As New ProductType("Tent Campers")
    Public Shared ReadOnly TravelTrailers As New ProductType("Travel Trailers")
    Public Shared ReadOnly TruckCampers As New ProductType("Truck Campers")

    Private Sub New(ByVal StringConstant As String)
        MyBase.New(StringConstant)
    End Sub
End Class

Passing as Arguments

Notice how ProductType can now be used as a type being passed to a method. It can also be easily used in Select Case statements, as a normal enumeration can be.

Public Sub SomeMethod(ByVal myProductType As ProductType)
    Select Case myProductType
        Case ProductType.FifthWheels
        Case ProductType.MotorHomes
        Case ProductType.TentCampers
        Case ProductType.TravelTrailers
        Case ProductType.TruckCampers
    End Select
End Sub

UpCasting

Strings can also be transparently upcast to your StringEnumeration.

Public Sub SomeMethod(ByVal myProductType As String)
    Select Case myProductType
        Case ProductType.FifthWheels
        Case ProductType.MotorHomes
        Case ProductType.TentCampers
        Case ProductType.TravelTrailers
        Case ProductType.TruckCampers
    End Select
End Sub

Casting to Strings and Concatenation

Dim myString As String = ProductType.FifthWheels
Dim myString As String = "Concatentation" & ProductType.FifthWheels

Looping through Names and Values

You can also loop through the names and values of your enumeration. That simple.

For Each ProductType As String In ProductType.Enum.GetNames
    'Loop through Enumeration Names
Next

For Each ProductType As String In ProductType.Enum.GetValues
    'Loop through Enumeration Values
Next

Identifying a StringEnumeration

If TypeOf(myObject) Is IStringEnumeration Then...

StringEnumeration Class

''' <summary>
''' Base Class for String Enumerations. Fully Represents
''' an Enumeration using Strings. Automatically casts & compares to Strings.
''' </summary>
''' <remarks></remarks>
Public MustInherit Class StringEnumeration(Of TStringEnumeration _
       As StringEnumeration(Of TStringEnumeration))
    Implements IStringEnumeration

    Private myString As String
    Sub New(ByVal StringConstant As String)
        myString = StringConstant
    End Sub

#Region "Properties"
    Public Class [Enum]
        Public Shared Function GetValues() As String()
            Dim myValues As New List(Of String)
            For Each myFieldInfo As System.Reflection.FieldInfo _
                                 In GetSharedFieldsInfo()
                Dim myValue As StringEnumeration(Of TStringEnumeration) = _
                  CType(myFieldInfo.GetValue(Nothing), _
                  StringEnumeration(Of TStringEnumeration))
                  'Shared Fields use a Null object
                myValues.Add(myValue)
            Next
            Return myValues.ToArray
        End Function

        Public Shared Function GetNames() As String()
            Dim myNames As New List(Of String)
            For Each myFieldInfo As System.Reflection.FieldInfo _
                     In GetSharedFieldsInfo()
                myNames.Add(myFieldInfo.Name)
            Next
            Return myNames.ToArray
        End Function

        Public Shared Function GetName(ByVal myName As _
               StringEnumeration(Of TStringEnumeration)) As String
            Return myName
        End Function

        Public Shared Function isDefined(ByVal myName As String) As Boolean
            If GetName(myName) Is Nothing Then Return False
            Return True
        End Function

        Public Shared Function GetUnderlyingType() As Type
            Return GetType(String)
        End Function

        Friend Shared Function GetSharedFieldsInfo() _
                      As System.Reflection.FieldInfo()
            Return GetType(TStringEnumeration).GetFields
        End Function

        Friend Shared Function GetSharedFields() As _
                      StringEnumeration(Of TStringEnumeration)()
            Dim myFields As New List(Of _
                         StringEnumeration(Of TStringEnumeration))
            For Each myFieldInfo As System.Reflection.FieldInfo _
                                 In GetSharedFieldsInfo()
                Dim myField As StringEnumeration(Of TStringEnumeration) = _
                    CType(myFieldInfo.GetValue(Nothing), _
                    StringEnumeration(Of TStringEnumeration))
                    'Shared Fields use a Null object
                myFields.Add(myField)
            Next
            Return myFields.ToArray
        End Function
    End Class
#End Region

#Region "Cast Operators"
    'Downcast to String
    Public Shared Widening Operator CType(ByVal myStringEnumeration _
           As StringEnumeration(Of TStringEnumeration)) As String
        If myStringEnumeration Is Nothing Then Return Nothing
        Return myStringEnumeration.ToString
    End Operator

    'Upcast to StringEnumeration
    Public Shared Widening Operator CType(ByVal myString As String) As _
                           StringEnumeration(Of TStringEnumeration)
        For Each myElement As StringEnumeration(Of TStringEnumeration) In _
                 StringEnumeration(Of TStringEnumeration).Enum.GetSharedFields
            'Found a Matching StringEnumeration - Return it
            If myElement.ToString = myString Then Return myElement
        Next
        'Did not find a Match - return NOTHING
        Return Nothing
    End Operator

    Overrides Function ToString() As String Implements IStringEnumeration.ToString
        Return myString
    End Function
#End Region

#Region "Concatenation Operators"
    Public Shared Operator &(ByVal left As StringEnumeration(Of _
           TStringEnumeration), ByVal right As StringEnumeration(Of _
           TStringEnumeration)) As String
        If left Is Nothing And right Is Nothing Then Return Nothing
        If left Is Nothing Then Return right.ToString
        If right Is Nothing Then Return left.ToString
        Return left.ToString & right.ToString
    End Operator

    Public Shared Operator &(ByVal left As StringEnumeration(Of _
           TStringEnumeration), ByVal right As IStringEnumeration) As String
        If left Is Nothing And right Is Nothing Then Return Nothing
        If left Is Nothing Then Return right.ToString
        If right Is Nothing Then Return left.ToString
        Return left.ToString & right.ToString
    End Operator
#End Region

#Region "Operator Equals"

    Public Shared Operator =(ByVal left As StringEnumeration(Of _
           TStringEnumeration), ByVal right As _
           StringEnumeration(Of TStringEnumeration)) As Boolean
        If left Is Nothing Or right Is Nothing Then Return False
        Return left.ToString.Equals(right.ToString)
    End Operator

    Public Overrides Function Equals(ByVal obj As Object) As Boolean
        If TypeOf (obj) Is StringEnumeration(Of TStringEnumeration) Then
            Return CType(obj, StringEnumeration(Of _
                   TStringEnumeration)).ToString = myString
        ElseIf TypeOf (obj) Is String Then
            Return CType(obj, String) = myString
        End If
        Return False
    End Function
#End Region

#Region "Operator Not Equals"
    Public Shared Operator <>(ByVal left As StringEnumeration(Of _
           TStringEnumeration), ByVal right As StringEnumeration(Of _
           TStringEnumeration)) As Boolean
        Return Not left = right
    End Operator

#End Region

End Class

'Base Interface without any Generics for StringEnumerations
Public Interface IStringEnumeration
    Function ToString() As String
End Interface

I hope this helps you! This has worked great for me.

License

This article, along with any associated source code and files, is licensed under The BSD License

Share

About the Author

Ryan D. Hatch

United States United States
No Biography provided

Comments and Discussions

 
Generalbugs and updates Pinmemberserhhio14-Aug-09 3:02 
GeneralRe: bugs and updates PinmemberRyan D. Hatch2-Sep-09 16:53 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.141223.1 | Last Updated 4 May 2009
Article Copyright 2009 by Ryan D. Hatch
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid