Click here to Skip to main content
15,881,882 members
Articles / Programming Languages / C#
Article

StringEnumerator

Rate me:
Please Sign up or sign in to vote.
3.92/5 (6 votes)
2 Feb 20073 min read 39.7K   246   27   7
A utility class relying on Generics and Attributes that allows strings to be enumerated (as enums)

Introduction

Ever wanted to treat strings like they were enumerations and put them through a switch statement? Ever wanted to bind the elements of an Enumeration to UI element but couldn't because the Enum names were not user friendly? How about storing a string as an Int in a database table and having that Int value strongly bound to a specific display string? The StringEnumerator utility class helps solve this problem by using Generics, Attributes, and Reflection to expose a set of static methods that transition between user friendly strings and Enum values.

Using the code

Of course, there's no real magic involved and C# doesn't intrinsically support string enumerators. The trick to achieving this effect is in the use of the DescriptionAttribute which we use to decorate the enumerator. The example below shows a Country enumeration with a few countries listed. The DescriptionAttribute is used to give the enum value a user friendly display name.

C#
///<summary>
/// Test Enumerator that contains some countries.
///</summary>

public enumCountry
{
    [Description("United States")]
    UnitedStates,
    Canada,
    Mexico,

    [Description("United Kingdom")]
    UK,

    [Description("Virgin Islands")]
    VirginIslands,
}

Using the class is really simple as will be demonstrated in the code samples to follow. When converting from a string back to an enumeration, the Parse and TryParse methods will try to parse the passed in string to return the enumerator. The difference between the two methods is that Parse will throw and InvalidCastException if the string could not be parsed whereas TryParse returns a boolean flag that indicates if the operation was successful. Otherwise, both methods are identical in that they will first try to match the string to the enum value directly. If a match cannot be made then the methods will look for a DescriptionAttribute to match the string against. As illustrated in the example below, both "United States" and "United States" will return the Country.UnitedStates enum value.

C#
//Match against the Description Attribute

string enumString = "United
States";

Country enumValue = StringEnumerator<Country>.Parse(enumString);

//Direct
match which is similar to Enum.Parse()

enumString = "UnitedStates";

enumValue = StringEnumerator<Country>.Parse(enumString);

// Try to parse the string.  Method will
// return false.

enumString = "United States of America";

success = StringEnumerator<Country>.TryParse(enumString,
            ref enumValue);

So the example above showed how to parse a string, now let's take a look at some of the methods that allow you to serialize an enumeration to a string or a collection. The StringEnumerator class provides a ToString method that will serialize an enumeration value to a string. This method will look for a DescriptionAttribute to return, and if one is not found, it will simply call built-in ToString method on the enum value to get the intrinsic behavior back to the user.

C#
// In this case, ToString finds a [Description(..)] attribute 
// and returns the descriptive string back.

Country enumValue = Country.UnitedStates;
string expected = "United States";

string actual = StringEnumerator<Country>.ToString(enumValue);

Assert.AreEqual(expected, actual);

// In this case the ToString doesn't find a [Description] attribute and 
// returns the built-in string representation.

enumValue = Country.Canada;
expected = Country.Canada.ToString();
actual = StringEnumerator<Country>.ToString(enumValue);
Assert.AreEqual(expected, actual);

The static methods that return a collection work in a similar fashion to generate a collection of strings from a given enumeration. This technique can be used to bind an enumeration to a UI element.

C#
// Generate a list of string from the enumerator to 
// populate a combobox

List<string>
enumValues = StringEnumerator<Country>.ToList();

comboBox.DataSource = enumValues;

Notes on Internationalization

Anybody who has had to internationalize (I18N) software below knows that hard-coding strings that are used for display purposes is not possible. Although, in its current state the StringEnumerator class does not support I18N, it could with some minor modifications be adapted to supply dynamic strings. One way to accomplish this would be to assign resource identifiers in the DescriptionAttribute in place of real strings. Then modify the parsing methods to lookup the real string value from a resource manager. This approach would then allow you to map integer values stored in a database to display values regardless of the local that the application is running within.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralAnother simple but type safe way Pin
robwood19-Jun-07 21:58
robwood19-Jun-07 21:58 
GeneralMuch simpler way Pin
Daniel Smolka15-Feb-07 23:48
Daniel Smolka15-Feb-07 23:48 
GeneralUsing StringEnumerator in a switch statement Pin
MCofer10-Feb-07 7:21
MCofer10-Feb-07 7:21 
GeneralThanks Pin
Netricity10-Feb-07 5:16
Netricity10-Feb-07 5:16 
QuestionWhat about the built-in Enum.Parse? Pin
Craig G. Wilson2-Feb-07 7:53
Craig G. Wilson2-Feb-07 7:53 
The built-in Enum.Parse method behaves exactly this way.

<br />
  Country c = (Country)Enum.Parse(typeof(Country), enumString);<br />


In addition, there are other static methods on the enum type.

<br />
  //get name.<br />
  string enumString = Enum.GetName(typeof(Country), Country.UnitedStates);<br />
<br />
  //gets all the names<br />
  string[] enumStrings = Enum.GetNames(typeof(Country));<br />
<br />


Not to knock your project because I'm sure you learned a lot, but why reinvent the wheel here?
AnswerRe: What about the built-in Enum.Parse? Pin
K.Collins6-Feb-07 5:59
K.Collins6-Feb-07 5:59 
GeneralSuggestion Pin
James Curran2-Feb-07 7:30
James Curran2-Feb-07 7:30 

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

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