Thursday, June 7, 2012

Enum with String (C#)

Sometimes you want to use enum with string values, not exact value of enum, but slightly different.
To achieve this we will create attribute class which will be used for storing string value for each enum.
In addition we need a helper class which will provide possibility to pull out these string values from enum.
OK, here is the attribute class:
public class StringValueAttribute : Attribute
{
    private string _value;
    
    public StringValueAttribute(string value)
    {
        _value = value;
    }
    
    public string Value
    {
        get { return _value; }
    }
}
Actually all we need now is a simple static method to pull out our string attributes from enum.
The method is inside our helper class with other helper methods.
public static string GetStringValue(Enum value)
{
    string output = null;
    Type type = value.GetType();

    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;
}
That's it. Now when you create an enum just add string attributes to it like this:
public enum VisibilityModes
{
    [StringValueAttribute("Visible Control")]
    Visible,
    [StringValueAttribute("Hidden Control")]
    Hidden,
    [StringValueAttribute("Collapsed Control")]
    Collapsed
}
And this is how you use it:
StringEnum.GetStringValue(VisibilityModes.Visible);
Download example source code - (Visual Studio 2010 Project)

5 comments:

  1. Is there any reason why you don't just use DisplayName or Display attributes from System.ComponentModel.DataAnnotations?

    ReplyDelete
    Replies
    1. Thank you for the question Bob.
      Be honest I didn't check this option.
      Probably you can use Display attributes too, I think it's quite similar to what I did here.

      Delete
  2. I'm working in a .Net Framework 2.0 project (seriously! In 2013!) and your code is exactly what I was looking for. It's worth a beer!

    ReplyDelete
  3. With .NET 4.0, I am using the following approach. It involves using the System.ComponentModel.Description attribute and a generic extension method on classes that implement IConvertible interface (Enum implements IConvertible).

    http://stackoverflow.com/a/30174850/689044

    ReplyDelete