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

String Enumerations in C#

By , 27 Jul 2005
 

Introduction

The idea of string enumerations in C# (and the lack thereof), has bothered me for a while. Enum's are useful things but only allow the storage of numeric types. What if you want to use strings?

Background

It struck me that I had a number of requirements when using string 'constants'.

I wanted the ability to define the values in-line and reference them like an enum value - e.g. MyEnum.MyString. It would also be nice to be able to reference the string values as a particular enum type, for the purposes of validation and strong-typing.

Options

Constants

The first thing I naturally gravitated towards was constants defined in a specific class. The following shows an example of this:

public sealed class MyConsts
{

    private MyConsts() {}

    public const string Val1 = "MyVal1";
    public const string Val2 = "MyVal2";
    public const string Val3 = "MyVal3";

}

The constants can be easily accessed as MyConsts.Val1 etc. This is extremely simple and reasonably neat. As these are constants the values are compiled in and as such can also be used nicely in switch statements.

Constants do have an interesting side effect in that the values are actually copied to any client code that uses the class. This means that client assemblies could potentially have out of date values if the values in the constants assembly were to change and it were redeployed without a client rebuild.

A possibly preferable alternative to the class would be to use a struct to house the constants, as this would always be created on the stack rather than the heap.

Static readonly

readonly values can be initialized with a value and changed only within a class's constructor. This effectively means their eventual value is not known at compile time. The code sample above can be changed slightly to illustrate this 'pseudo const'.

public sealed class MyConsts
{

    private MyConsts() {}

    public static readonly string Val1 = "MyVal1";
    public static readonly string Val2 = "MyVal2";
    public static readonly string Val3 = "MyVal3";
}

Values are again accessed in exactly the same way e.g. MyConsts.Val3, but as the values are conceptually dynamic, they will always be accessed from the class where they are defined. This does also mean that cannot be evaluated in switch statements.

Enums

Enum's can only contain numeric values right? Well, each value can actually be decorated with custom attributes, which means it's possible to extend a normal enum to contain string values as follows:

public enum HandTools
{
    [StringValue("Cordless Power Drill")
    Drill = 5,
    [StringValue("Long nose pliers")
    Pliers = 7,
    [StringValue("20mm Chisel")
    Chisel = 9

}

Enums can of course be declared without explicit numeric values, in which case each item will have implicit numeric items (starting from 0). This can be a bit of a pain when debugging (and provides a slight performance hit), so Microsoft suggests always declaring a numeric value.

The StringValue attribute is a simple attribute class (derived from System.Attribute) that is constructed with a string and exposes that string via a single Value property:

public class StringValueAttribute : System.Attribute
{

    private string _value;

    public StringValueAttribute(string value)
    {
        _value = value;
    }

    public string Value
    {
    get { return _value; }
    }

}

We now need some way of accessing these strings (via the StringValue attribute) and using them as part of our standard enum type.

StringEnum

The StringEnum class acts as a wrapper for string value access in enumerations. It assumes that enums wishing to expose string values do so via the StringValue attribute. The StringEnum class has static and instance portions and provides the following static methods:

  • Parse : Parse a string value and return the corresponding enum value.
  • GetStringValue : Return the string value associated with the given enum value.
  • IsStringValueDefined : Indicate the existence or non-existence of an enum value with the given string value.

The GetStringValue is shown below. This takes in an enum value and performs a fast type lookup before retrieving the StringValue attribute (if it can find it). The string value is then returned. We use a static Hashtable (_stringValues) to cache results (keyed by enum value) to avoid the minor reflection performance hit on subsequent requests.

public static string GetStringValue(Enum value)
{
    string output = null;
    Type type = value.GetType();

    //Check first in our cached results...
    if (_stringValues.ContainsKey(value))
      output = (_stringValues[value] as StringValueAttribute).Value;
    else 
    {
        //Look for our 'StringValueAttribute' 
        //in the field's custom attributes
        FieldInfo fi = type.GetField(value.ToString());
        StringValueAttribute[] attrs = 
           fi.GetCustomAttributes(typeof (StringValueAttribute), 
                                   false) as StringValueAttribute[];
        if (attrs.Length > 0)
        {
            _stringValues.Add(value, attrs[0]);
            output = attrs[0].Value;
        }
    }

    return output;
}

Case-insensitive overloads are provided for the Parse and IsStringValueDefined methods.

Similar instance methods are provided (using a constructor taking the enum's type), with an additional method for use in data binding:

  • GetListValues : Return an IList for data binding the StringEnum values.

Using the code

The code can be simply used by extending any enum to include [StringValue("")] attributes. You can then use the StringEnum class to retrieve the values as follows:

//Values intentionally unordered...

public enum CarType
{
    [StringValue("Saloon / Sedan")] Saloon = 5,
    [StringValue("Coupe")] Coupe = 4,
    [StringValue("Estate / Wagon")] Estate = 6,
    [StringValue("Hatchback")] Hatchback = 8,
    [StringValue("Utility")] Ute = 1,
}


public void TestMethod()
{
    MessageBox.Show(StringEnum.GetStringValue(CarType.Estate));
    //The line above shows 'Estate / Wagon'

    MessageBox.Show(StringEnum.Parse(typeof(CarType), 
                     "estate / wagon", true).ToString());
    //The line above converts back to an enum 
    //value from String Value (case insensitive)
    //and shows 'Estate'

    int enumValue = (int)StringEnum.Parse(typeof(CarType), 
                                     "estate / wagon", true);
    MessageBox.Show(enumValue.ToString());
    //The line above does the same again but this time shows 
    //the numeric value of the enum (6)
}

Points of interest

The source project has a full set of NUnit tests to illustrate each method, and the demo project shows other items such as examples of data binding with StringEnum.

Have fun!

History

  • (29/07/2005) - Updated source zip file with hashtable caching for GetStringValue.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

CodeBureau - Matt Simner
Software Developer (Senior) Codebureau
Australia Australia
Member
Started with COBOL/CICS/DB2 - ended up with C#/ASP.NET. I'm a half-geek (or so my wife tells me!)

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralNicememberJohnDetroit7 Jun '12 - 4:33 
Simmilar to this solution: Enum with String (C#)
QuestionI've wrote an article related to this context.memberShlomiO2 Jun '12 - 3:27 
It can be found here - http://www.shloemi.com/2012/06/csharp-const-constant-explained-by-faq-qa/
GeneralMy vote of 4memberInfernalBlackNecroCorpseSodomy400028 May '12 - 16:31 
where is String Enum class code?
QuestionNot able to run this projectmemberbaskaran chellasamy10 May '12 - 5:32 
When i am running this project Error occurred like "A project with an output type of class library cannot be started directly.
In ordered to debug this project,add an executable project to this solution which reference the library project. set the executable project as a start up project. I am new to this.please help me.
Questionnice articlememberRupeshKumar24 Feb '12 - 4:56 
Well explained all the differences.
QuestionCode license [modified]memberMember 835708128 Oct '11 - 9:07 
Could you specify what is the license of this code?

modified 29 Oct '11 - 12:46.

AnswerRe: Code licensememberCodeBureau - Matt Simner7 Nov '11 - 9:50 
Hi there, apologies for the lack of license - it's now CPOL - so all yours!
GeneralMy vote of 4memberalmerak17 Jun '11 - 11:13 
Excellent article
GeneralWhat's wrong with the first two optionsmemberMartinFister18 Apr '10 - 7:39 
Are there any flaws to your first suggestions? You seemed to rule out constants and readonly variables but didn't highlight quite what was wrong with these options
 

Martin of fendi handbag
GeneralRe: What's wrong with the first two optionsmemberCetto28 Jan '12 - 14:12 
problem is the constants aren't mapped to each enum value
GeneralIf using .NET 3.5+ [modified]memberJoe Gershgorin1 Apr '10 - 17:00 
Here are static versions of some of the helpers that return IEnumerables (great for LINQ query support and Silverlight compatibility);
/// <summary>
/// Gets the string values associated with the enum.
/// </summary>
/// <returns>IEnumerable of strings</returns>
public static IEnumerable<string> GetStringValues(Type enumType)
{           
    //Look for our string value associated with fields in this enum
    foreach (FieldInfo fi in enumType.GetFields())
    {
        //Check for our custom attribute
        var stringValueAttributes = fi.GetCustomAttributes(typeof(StringValueAttribute), false) as StringValueAttribute[];
        if (stringValueAttributes.Length > 0)
        {               
            yield return stringValueAttributes[0].Value;
        }
    }            
}
 
/// <summary>
/// Gets the values as a IEnumerable datasource.
/// </summary>
/// <returns>IEnumerable for data binding</returns>
public static IEnumerable<DictionaryEntry> GetEnumsAsDictionary(Type enumType)
{            
    var underlyingType = Enum.GetUnderlyingType(enumType);
               
    //Look for our string value associated with fields in this enum
    foreach (var fieldInfo in enumType.GetFields())
    {
        //Check for our custom attribute
        var stringValueAttributes = fieldInfo.GetCustomAttributes(typeof(StringValueAttribute), false) as StringValueAttribute[];
        if (stringValueAttributes.Length > 0)
        {
            yield return new DictionaryEntry(Convert.ChangeType(Enum.Parse(enumType, fieldInfo.Name, false), underlyingType, System.Globalization.CultureInfo.InvariantCulture), stringValueAttributes[0].Value);
        }                    
    }            
}
 
Usage:
 
var list1 = StringEnum.GetStringValues(typeof (MyEnum)).ToList();
var list2 = StringEnum.GetEnumsAsDictionary(typeof(MyEnum)).ToList();
modified on Thursday, April 1, 2010 11:11 PM

GeneralMisuse of sealed classmemberSAKryukov11 Jan '10 - 6:07 
You misuse sealed class with private constructor on a regular basis.
In your example you should remove 'sealed' keyword and private constructor and add keyword 'static' to the class.
Static class is not derivable; and it will not allow any constructors because it does not allow instantiation.
Please don't set up wrong usage pattern for your readers.
 
Thank you.
 
Sergey A Kryukov

GeneralGeneric Parsememberpsay27 Oct '09 - 17:36 
Firstly this is great!
 
Second when setting the value bach from the database I used the Parse method as defined
_ActiveStatus = (VendorActiveStatus)StringEnum.Parse(typeof(VendorActiveStatus), dr.GetString("ActiveStatus"));
 
However the code can be stream lined further by adding the following Generic method(s)
 
 
public static T Parse<T>(string stringValue)
{
    return (T)Parse(typeof(T), stringValue);
}
 
public static T Parse<T>(string stringValue, bool ignoreCase)
{
    return (T)Parse(typeof(T), stringValue, ignoreCase);
}
 
 
Resulting in this
 
 
_ActiveStatus = StringEnum.Parse<VendorActiveStatus>(dr.GetString("ActiveStatus"));
 

GeneralYou have a good base, now think about how to add behaviors.memberhandcraftsman24 Sep '09 - 5:40 
You have a good base, now think about how to add behaviors. You start with a sealed class with strings as follows:
 
public sealed class Animal
{
 
private Animal() {}
 
public static readonly string Dog = "dog";
public static readonly string Eagle = "eagle";
public static readonly string Dolphin = "dolphin";
}

 
Then you cleverly tack on attributes because you cannot switch on Animal static strings in switch statements. Now imagine that eliminating switch statements is important because you don't want your code to violate the Open closed principle[^] - essentially you don't want to have to hunt down all the switch statements and add a new case whenever you add a new type (i.e. Spider = "spider").
 
This means instead of a switch...
 

public void MakeSound(Animal animal)
{
switch(animal)
{
case "dog":
MakeDogSound();
break;
case "eagle":
MakeEagleSound();
break;
case "dolphin":
MakeDolphinSound();
break;
case "spider":
MakeSpiderSound();
break;
}
}

 
you use polymorphism to support the desired behavior:
 

public sealed class Animal
{
public string Name { get; private set; }
public Func GetSound { get; private set; }
 
private Animal(string name, Func getSound)
{
Name = name;
GetSound = getSound;
}
 
public static readonly Animal Dog = new Animal("dog", () => "woof");
public static readonly Animal Eagle = new Animal("eagle", () => "scree");
public static readonly Animal Dolphin = new Animal("dolphin", () => "ee ee");
public static readonly Animal Spider = new Animal("spider", () => "(no sound)");
}

 
and your "switch" code becomes
 

public void MakeSound(Animal animal)
{
Console.WriteLine(animal.GetSound());
}

 
Here's an example from one of our open source projects:
http://code.google.com/p/nhibernate-hbm-to-fluent-converter/source/browse/trunk/Converter/PropertyMappingType.cs[^]
 
I hope you find this useful.
GeneralToString() example, better fit for my situation ...memberwardj21 Aug '09 - 4:04 
Came across you solution while I was looking for a simple way to convert between Enums and Strings.
 
Turns out, this solution was a better fit for me - so I thought I'd share to provide another example for anybody in the same situation:
 
http://msdn.microsoft.com/en-us/library/system.enum.tostring(VS.71).aspx[^]
 
To paraphrase the above link, it essentially solves the string/enum problem as follows:
 
enum Colors {Red, Green, Blue, Yellow};
 
Colors color_enum = Colors.Yellow;
string color_text = color_enum.ToString("g");
Console.WriteLine(color_text);
GeneralRe: ToString() example, better fit for my situation ...memberCodeBureau - Matt Simner21 Aug '09 - 12:36 
Absolutely - good point. The "g" format certainly fits the bill for retrieving single word names. The solution in the article (or any of the other [attribute] based solutions mentioned in the comments is really intended for support of multi-word names and translating etc.
 
As always - choose the simplest solution that fits your needs Smile | :)
Generalcould be more easy to use [modified]memberhackrogenius29 Mar '09 - 2:11 
you can write some extended methods like
 
//------------------Methods---------------------------
public static string GetStringValue(this Enum e)
            {
                  return StringEnum.GetStringValue(e);
            }
 
//and
 
public static T GetEnum<T>(this String na, String value)
            {
                  return (T)StringEnum.Parse(typeof(T), value);
            }
//----------------------End Methods---------------------
 
and that would be very nice   ...
 
suppose i have an enum
 
enum Cars
{
[StringValue("h o n d a")]Honda,
[Stringvalue("t_o_y_o_t_a")]Toyota
}
 
//------------------------EXAMPLES-----------------------
string hondaString = Cars.Honda.GetStringValue();
 
//;)
 
//and
 
Cars carFromHonda = "".GetEnum<Cars>(hondaString);
//------------------------END EXAMPLES-------------------
 
how   cool?
 
--
ASif Ashraf
MCPD, MCAD.NET
Asif.Log@gmail | hotmail.com
92-42-5006784
Technical Lead
Store Secured Inc
modified on Sunday, March 29, 2009 8:21 AM
GeneralRe: could be more easy to use [modified]memberDavid Logan29 Mar '09 - 13:52 
This alternative solution will only work in c# 3.0 (.Net 3.5) and above.
 
It relies on Extension Methods, which were only added to c# in 3.0 (.Net 3.5).
 
modified on Sunday, March 29, 2009 8:08 PM

GeneralRe: could be more easy to use [modified]memberJoe Gershgorin1 Apr '10 - 11:27 
For best of both worlds, I created an extension class that wraps the existing methods.
 
Also had to deal with a few issues concerning Silverlight compatibility:
 
1.) Hashtable type doesn't exist in SL, used Dictionary<Enum, StringValueAttribute> instead.
 
2.) ArrayList doesn't exist in SL, used List<string> and List<DictionaryEntry> instead.
 
3.) Enum.Parse in SL doens't have an overload where ignoreCase value can be omitted.
 
4.) string.Compare doesn't have an overload where a bool ignorecase value can be passed. Use the following instead:
 
if (ignoreCase)
{
     if (string.Compare(enumStringValue, stringValue, StringComparison.InvariantCultureIgnoreCase) == 0)
     {
          output = Enum.Parse(type, fi.Name, ignoreCase);
          break;
     }
}
else
{
     if (string.Compare(enumStringValue, stringValue) == 0)
     {
          output = Enum.Parse(type, fi.Name, ignoreCase);
          break;
     }
}
 
5.) Convert.ChangeType requires an IFormatProvider argument, I used "System.Globalization.CultureInfo.InvariantCulture".
modified on Thursday, April 1, 2010 8:19 PM

GeneralDescriptionAttributememberJaime Olivares25 Jun '08 - 4:14 
Why to create a new attribute class like StringValueAttribute?
You can use already existing System.ComponentModel.DescriptionAttribute, it is widely used in .net like in PropertyGrid control.
DescriptionAtrribute has a property called Description.
 
Best regards,
Jaime.

GeneralRe: DescriptionAttributememberCodeBureau - Matt Simner28 Jul '08 - 14:16 
You're completely right. The Description attribute (which I found myself some time ago but didn't update the code Blush | :O ) could easily replace the StringValue attribute.
GeneralStatic Class optionmemberEdw22 Feb '08 - 8:22 
Similar solution but using a static class:
 
Sample code:
 
namespace mynamespace.utils.Constants
{
public static class Constants
{
// no constructor
 
public readonly static String SomeValue = "some value";
public readonly static String SomeOtherValue = "some other value";
....
}
}
 
Usage:
 
using mynamespace.utils.Constants
 

string s = "some value";
if (Constants.SomeValue == s)
...
GeneralTaking the static class one step further.memberJames Coe10 Jun '08 - 10:57 
This is a valid approach but lacks a lot of the functionality of an enum like the ability to parse, getting the list of enum values, etc. Take a look at the solution I came up with. SpecializedEnum[^] on Codeplex duplicates almost the entire functionality of an enum by extending this basic static approach.
QuestionHow I solved the same problem [modified]memberAzola73 Oct '07 - 5:33 
This is how I solved the same problem
 
public enum CarType
{
     Saloon,
     Coupe,
     Hatchback,
     Bakkie
}
 
public static class CarTypeEnum
{
     public static string getString(CarType aCarType)
     {
          string lValue = string.Empty;
         
          switch(aCarType)
          {
               case CarType.Saloon:
                    lValue = "Saloon \ Sedan";
                    break;
              
               case CarType.Coupe:
                    lValue = "Coupe";
                    break;
                   
               case CarType.Hatchback:
                    lValue = "Hatchback";
                    break;
                   
               case CarType.Bakkie:
                    lValue = "Bakkie \ Truck";
                    break;
          }
         
          return lValue;
     }
}
 

-- modified at 7:50 Tuesday 9th October, 2007
AnswerRe: How I solved the same problemmember263923 Feb '08 - 14:08 
I like this solution Big Grin | :-D
There seems to be no bottlenecks involved and is very simple and clean.
 
Question regarding all of these solutions: Is it better put the constants in a seperate .dll than the client application? Seems to me that would be ideal in the case that business rules might dictate the changing of verbage of the messages. Then you could simply push out that .dll as an update rather than the whole client application.
 
Along those same theories, what performance hit is there storing constants in an xml file that the client reads? Then no recompiling is ever necessary even for the constants. Thoughts?
GeneralAdded a small bitmemberShilshul13 Nov '06 - 7:04 
if (attrs.Length > 0) {
m_StringValues.Add(value, attrs[0]);
output = attrs[0].Value;
}
else {
output = Enum.GetName(value.GetType(), value);
m_StringValues.Add(value, new StringValueAttribute(output));
}
 
Added the "else" section, which returns the string that makes the enum value, if the attribute is not found.
GeneralSlight optimizationmemberKeith Farmer27 Jul '05 - 8:43 
If I'm correct, there's going to be a performance hit due to reflecting on the attributes every access. You can probably soften the blow by reflecting, the first time, and caching the results.
 
In 1.1, a Hashtable, with Keys of (Type, enum Value) would work. In 2.0, you could use lightweight code generation and generics to create a big switch and avoid the lookup.
 
Also, it's been recommended as a best-practice to always specify the underlying values of your enum members. It turns out that the enum values are translated to their underlying types when compiled, and so you suffer the same problem as you would with const strings (and makes it annoying when reflecting through a method). If no values are specified, the default value is dependent on the order of members in the enum. Specifying ahead of time protects against reordering of the enum members.
 

GeneralRe: Slight optimizationmemberCodeBureau - Matt Simner27 Jul '05 - 12:24 
Thanks Keith!
 
I certainly take the point about performance. I could easily introduce a level of caching for both static and instance methods. I guess I was trying to keep it simple for the moment, but that's a good next step I'll try to accommodate soon.
 
The underlying value omission is an oversight on my part. I think I was trying to illustrate that you could use the string enums as a name/value pair mechanism as well as an extended enum (with explicit values). I find the same thing annoying when hitting F12 to find an enum value only to find I've got to start counting from zero!
 
I'll try and incorporate both points in an update, and thanks again for the feedback.
GeneralRe: Slight optimizationmemberKeith Farmer27 Jul '05 - 12:32 
F12 does ...?
 
This is a novel approach to the problem, and it solves some of the headaches. I'd not have thought about using attributes for this.
GeneralRe: Slight optimizationmemberCodeBureau - Matt Simner27 Jul '05 - 12:37 
Sorry... F12 to jump to the declaration of the enum when debugging/coding in VS.
GeneralRe: Slight optimizationsussKent Boogaart11 Aug '05 - 17:36 
Actually, reflection metadata is cached by the runtime after retrieval. I doubt you'd any perf improvement by implementing your own cache. You'd have to measure though...
QuestionRe: Slight optimizationmemberColin Bowern22 Feb '06 - 10:04 
Hey Keith..
 
I was wondering if you could expand on your idea for the 2.0 code generation/generic idea? I'm not quite sure I follow and I'm working in 2.0 with a need to do a string enum.
AnswerRe: Slight optimizationmemberKeith Farmer22 Feb '06 - 11:30 
It's been a while, but I think the idea was that if you were to have a cache on some EnumToString class, you could call EnumToString.ToString(Enum), where ToString would access the cache and produce the string. But to do that, you need to generate the cache.
 
Alternatively, in 2.0, you could use a runtime-generated switch statement that was stored in a delegate. On the first call, the delegate would be null, and so you could use LCG to create a DynamicMethod instance and store it in the delegate, and then call the delegate with the enum value as the argument.
 
See http://msdn2.microsoft.com/en-us/library/80h6baz2(en-US,VS.80).aspx[^] and http://msdn2.microsoft.com/en-us/library/exczf7b9.aspx[^].

 
-----
Keith J. Farmer [MSFT:VC#/DLinq]
Generalnice, but for simple things...sussAnonymous27 Jul '05 - 2:48 
where you just need a string representation of the enum value you can just do:
 

Console.WriteLine(Enum.GetName(typeof(MyEnum),MyEnum.MyValue));

 
which should output "MyValue". This is enough for many tasks I have encountered.
GeneralRe: nice, but for simple things...memberPaul Brower27 Jul '05 - 8:34 
Or easier yet:
 
public enum TestEnum
{
Item1,
Item2,
Item3
}
 
public void TestIt()
{
TestEnum myenum = TestEnum.Item1 ;
Console.WriteLine(myenum.ToString()) ;
}
 
//this will write out "Item1"
 
It doesn't get much simpler for simple enums
GeneralRe: nice, but for simple things...memberKeith Farmer27 Jul '05 - 8:35 
True, however Enum.GetName() isn't suitable where the string needs to contain non-ID characters, such as spaces.

GeneralRe: nice, but for simple things...memberRobert Kozak27 Jul '05 - 13:47 
Re: nice, but for simple things... Robert Kozak 19:42 27 Jul '05
So let's combine both things:
 
Add a Hashtable to the StringEnum class:

private static Hashtable _StringValueAttributes = new Hashtable();

 
Then change GetStringValue method.
 
public static string GetStringValue(Enum value)
{
string output = null;
Type type = value.GetType();
 
if (_StringValueAttributes.ContainsKey(type))
{
return (_StringValueAttributes[type] as StringValueAttribute).Value;
}
else
{

//Look for our 'StringValueAttribute' in the field's custom attributes
FieldInfo fi = type.GetField(value.ToString());
StringValueAttribute[] attrs = fi.GetCustomAttributes(typeof (StringValueAttribute), false) as StringValueAttribute[];
if (attrs.Length > 0)
{
output = attrs[0].Value;
_StringValueAttributes.Add(type, attrs[0]);
}
else
{
output = value.ToString();
}

 
return output;
}
}

 

of course you will need to make this similar change to the other methods that access the StringValueAttributes.
 
With this it caches StringValueAttribute so that if you have to do the Reflection each time. and If an attribute is not found then just use the Enum's ToString to get its string representation.
 
-- Robert

GeneralRe: nice, but for simple things...memberCodeBureau - Matt Simner27 Jul '05 - 15:05 
Thanks!
That's nice and simple, although the key for the Hashtable needs to be the enum value rather than the type (as the 'type' is the Enum itself, and would return the same string value for all values in the enum)
 
I'll update the code (with new unit test) and post an article update to incorporate the changes. I haven't applied the same change to the methods returning multiple values as I think the need for optimisation is less pressing, and these rely on reflection already to enumerate the enum's fields.

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

Permalink | Advertise | Privacy | Mobile
Web02 | 2.6.130516.1 | Last Updated 27 Jul 2005
Article Copyright 2005 by CodeBureau - Matt Simner
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid