1

I was looking for a way to enumerate String types in (vb).NET, but .NET enums only accept numeric type values.

The first alternative I came across was to create a dictionary of my enum values and the string I want to return. This worked, but was hard to maintain because if you changed the enum you would have to remember to also change the dictionary.

The second alternative was to set field attributes on each enum member, and retrieve it using reflection. Surely enough this worked aswell and also solved the maintenance problem, but it uses reflection and I've always read that using reflection should be a last resort thing.

So I started thinking and I came up with this: every ASCII character can be represented as a hexadecimal value, and you can assign hexadecimal values to enum members. You could get rid of the attributes, assign the hexadecimal values to the enum members. Then, when you need the text value, convert the value to a byte array and use System.Text.Encodings.ASCII.GetString(enumMemberBytes) to get the string value.

Now speaking out of experience, anything I come up with is usually either flawed or just plain wrong. What do you guys think about this approach? Is there any reason not to do it like that?

Thanks.

EDIT

As pointed out by David W, enum member values are limited in length, depending on the underlying type (integer by default). So yes, I believe my method works but you are limited to characters in the ASCII table, with a maximum length of 4 or 8 characters using integers or longs respectively.

Steven Liekens
  • 13,266
  • 8
  • 59
  • 85
  • 1
    Perhaps I'm not understanding your question properly, but the enumeration type just implies an int type. In your scenario, assuming a four-byte length for an int (as on a 32-bit platform), you'd be constrained to four-character (ASCII-encoded) enumeration "strings." Now, having said that, keep in mind that you can declare textual (symbolic) names in your enum values that can, in turn, be readily converted to Strings when you need them. – David W Apr 24 '12 at 19:14
  • Ahh I just ran into that problem. Changing the underlying type to Long doubles the maximum length to 8 characters, but that's still not enough for what I'm trying to do. – Steven Liekens Apr 24 '12 at 19:28
  • are you trying How to enumerate an enum? http://stackoverflow.com/questions/105372/how-to-enumerate-an-enum – volody Apr 24 '12 at 20:51
  • @volody No I'm simply trying to assign text values to my enum members, which is indeed possible the way I described if you are comfortable with an upper limit of 8 characters, limited to characters in the ASCII table (meaning no accents or funny symbols). – Steven Liekens Apr 24 '12 at 21:32

1 Answers1

1

The easiest way I have found to dynamically parse a String representation of an Enumeration into the actual Enumeration type was to do the following:

Private EnumObject
     [Undefined]
     ValueA
     ValueB
End Enum

dim enumVal as EnumObject = DirectCast([Enum].Parse(GetType(EnumObject), "ValueA"), EnumObject)

This removes the need to maintain a dictionary and allows you to just handle strings instead of converting to an Int or a Long. This does use reflection, but I have not come across any issues as long as you catch and handle any exceptions with the String Parse.

j3ff
  • 11
  • 2
  • Great stuff, but that's not the question though. To clarify: I want to have an enumeration of strings for use in methods that take a strongly typed enum value as a parameter, as opposed to using constants which are not strongly typed. The closest I can get to having real string enumerations is to set the value that I need as the member name, and use its .ToString method. But something about doing that just doesn't feel right. – Steven Liekens Apr 24 '12 at 21:39
  • Or in other words: I need to do it the other way around. I receive ValueA or ValueB and I need to return "ValueA" or "ValueB". Except ofcourse that the values will be substantially different from the enum names so calling ToString just won't cut it unless I change the actual enum names (see previous comment). – Steven Liekens Apr 24 '12 at 22:26
  • I see. So you want something that will give you a friendly string representation of the Enum instead of doing .ToString? – j3ff Apr 25 '12 at 00:07
  • Here is a link that might help: http://weblogs.asp.net/grantbarrington/archive/2009/01/19/enumhelper-getting-a-friendly-description-from-an-enum.aspx – j3ff Apr 25 '12 at 00:07
  • That article describes what I've already covered in my question: setting field attributes. And his code doesn't even implement a form of caching to handle subsequent requests without the performance hit that comes with using reflection. – Steven Liekens Apr 25 '12 at 06:52
  • What about creating a config file to hold the values? Populate and access it with the singleton pattern. It can be initalized on startup so all values will be dynamically pulled in from the config. Using a singleton in combination with a config will allow for easier maintenance and greater variety. – j3ff May 03 '12 at 02:14
  • Not a bad idea, but I think most people will still go for the reflection approach. I've played around with it a little more and I find that if you cache the attribute values in a dictionary, it's almost as fast as using true String enums. Yet you don't have to maintain the dictionary's contents because you can just set the attribute on each enum member as you code. – Steven Liekens May 03 '12 at 04:15