views:

264

answers:

3

I have a class in VB with some constants that represent the string name of my security roles. I need to be able to call a function to return to me a string array(or collection, or whatever) of the values of each of these constants. I will be using it to make sure that my databases Roles table has the same roles as coded into the application.

Public Class Roles
    Public Const Administrator = "Administrator"
    Public Const BasicUser = "Basic User"
    Public Const PowerUser = "Power User"
End Class

I'm looking to run a function, i.e. ClassConstantsToStringArray(gettype(Roles)) that will return to me "Administrator","Basic User","Power User"

I'm know reflection is the way to go, I just don't know enough about using it yet to get what I want. I found a function on the net that would return to me the constant names in a FieldInfo array but still don't have enough smarts to make that work for me.

Thanks.

A: 

Why not use an Enum?

Ken Keenan
Enums cannot contain string values.
Jon Seigel
Enums in VB.NET cannot contain strings as values. In Java they can.
vanslly
Actually, VB.Net can do a very good job _simulating_ string enums. I have a couple posts here on the topic, but I'm having trouble finding them at the moment.
Joel Coehoorn
What I'm trying to get at is that an enum makes the most sense. Creating a pseudo-enum by putting a bunch of hard-coded strings in a class and reflecting them out again just seems... inelegant. Plus, it's gonna break if the app ever needs to be localized. I'd put the strings in resources and use a `TypeConverter` like this article (http://www.codeproject.com/KB/cs/LocalizingEnums.aspx) describes.
Ken Keenan
+2  A: 

You can build an object that is nearly identical to a string enum in VB.Net. See my previous post on the topic here:

http://stackoverflow.com/questions/940002/getting-static-field-values-of-a-type-using-reflection/940340#940340

Joel Coehoorn
That's a nice solution :)
vanslly
I liked this solution also but since I was 99% of the way there, I just stuck with what I was working with. +1 though.
Dennis
+2  A: 

Ok, here's how it is done. I didn't do this on my own though, http://weblogs.asp.net/whaggard/archive/2003/02/20/2708.aspx had the answer, I just ran it through a C# to VB.Net converter.

Function GetStringsFromClassConstants(ByVal type As System.Type) As String()
    Dim constants As New ArrayList()
    Dim fieldInfos As FieldInfo() = type.GetFields(BindingFlags.[Public] Or _ 
        BindingFlags.[Static] Or BindingFlags.FlattenHierarchy)

    For Each fi As FieldInfo In fieldInfos
        If fi.IsLiteral AndAlso Not fi.IsInitOnly Then
            constants.Add(fi)
        End If
    Next

    Dim ConstantsStringArray as New System.Collections.Specialized.StringCollection

    For Each fi as FieldInfo in _ 
        DirectCast(constants.ToArray(GetType(FieldInfo)), FieldInfo())
        ConstantsStringArray.Add(fi.GetValue(Nothing))
    Next

    Dim retVal(ConstantsStringArray.Count - 1) as String
    ConstantsStringArray.CopyTo(retval,0)
    Return retval    
End Function
Dennis