Dictionary of Enum Values as strings

11,676

Solution 1

Here is one way you could store the mapping in a dictionary and retrieve values later:

var myDict = new Dictionary<PackageUnitOfMeasurement,string>();
myDict.Add(PackageUnitOfMeasurement.LBS, "02");
...

string code = myDict[PackageUnitOfMeasurement.LBS];

Another option is to use something like the DecriptionAttribute to decorate each enumeration item and use reflection to read these out, as described in Getting attributes of Enum's value:

public enum PackageUnitOfMeasurement
{
        [Description("02")]
        LBS,
        [Description("03")]
        KGS,
};


var type = typeof(PackageUnitOfMeasurement);
var memInfo = type.GetMember(PackageUnitOfMeasurement.LBS.ToString());
var attributes = memInfo[0].GetCustomAttributes(typeof(DescriptionAttribute),
    false);
var description = ((DescriptionAttribute)attributes[0]).Description;

The benefit of the second approach is that you keep the mapping close to the enum and if either changes, you don't need to hunt for any other place you need to update.

Solution 2

You can specify the number value of the enum elements

public enum PackageUnitOfMeasurement {
    None = 0,
    LBS = 2,
    KGS = 3,
    TONS = 0x2a
};

Then you can simply convert the units with

uom.Code = ((int)unit).ToString("X2");

NOTE:

The fundamental question is, whether it is a good idea to hard-code the units. Usually this sort of things should be put into a lookup table in a DB, making it easy to add new units at any time without having to change the program code.


UPDATE:

I added an example containing a HEX code. The format "X2" yields a two digit hex value. Enter all numbers greater than 9 in hex notation like 0xA == 10, 0x10 == 16 in c#.

Solution 3

I would use attributes attached to the enum. Like this:

var type = typeof(PackageUnitOfMeasurement);
var memInfo = type.GetMember(PackageUnitOfMeasurement.LBS.ToString());
var attributes = memInfo[0].GetCustomAttributes(typeof(DescriptionAttribute),
    false);
var description = ((DescriptionAttribute)attributes[0]).Description;

This is taken from this question, Getting attributes of Enum's value. Which asks specifically about returning Enum attributes.

Solution 4

Oded's solution is fine, but an alternative that I've used in the past is to use attributes attached to the enum values that contain the corresponding string.

Here's what I did.

public class DisplayStringAttribute : Attribute
{
    private readonly string value;
    public string Value
    {
        get { return value; }
    }

    public DisplayStringAttribute(string val)
    {
        value = val;
    }
}

Then I could define my enum like this:

public enum MyState 
{ 
    [DisplayString("Ready")]
    Ready, 
    [DisplayString("Not Ready")]
    NotReady, 
    [DisplayString("Error")]
    Error 
};

And, for my purposes, I created a converter so I could bind to the enum:

public class EnumDisplayNameConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        Type t = value.GetType();
        if (t.IsEnum)
        {
            FieldInfo fi = t.GetField(value.ToString());
            DisplayStringAttribute[] attrbs = (DisplayStringAttribute[])fi.GetCustomAttributes(typeof(DisplayStringAttribute),
                false);
            return ((attrbs.Length > 0) && (!String.IsNullOrEmpty(attrbs[0].Value))) ? attrbs[0].Value : value.ToString();
        }
        else
        {
            throw new NotImplementedException("Converter is for enum types only");
        }
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

Oded's solution probably performs faster, but this solution has a lot of flexibility. You could add a whole bunch of attributes if you really wanted to. However, if you did that, you'd probably be better off creating a class rather than using an enum!

Share:
11,676

Related videos on Youtube

PUG
Author by

PUG

rupam shunyata shunyataiva rupam

Updated on June 28, 2022

Comments

  • PUG
    PUG almost 2 years

    I am trying to make an API, one function in that API takes Enum as parameter which then corresponds to a string which is used.

    public enum PackageUnitOfMeasurement
    {
            LBS,
            KGS,
    };
    

    The trivial method to code this will have to list every case in code. But as their are 30 cases so I am trying to avoid that and use Dictionary Data Structure, but I can't seem to connect the dots on how will I relate value to enum.

    if(unit == PackageUnitOfMeasurement.LBS)
           uom.Code = "02";  //Please note this value has to be string
    else if (unit == PackageUnitOfMeasurement.KGS)
           uom.Code = "03";
    
    • Rawling
      Rawling about 12 years
      Please note this value has to be string - but will all the string values be string representations of integers, and distinct integers at that? If so you should set the integer underlying each enum value, and then write a function to correctly convert the integers to the string representation you want e.g. 2=> "02" etc.
  • Gabe
    Gabe about 12 years
    This sounds promising, but it's hard to imagine what it would look like. Can you post an example?
  • Ben Hoffman
    Ben Hoffman about 12 years
    See my answer. It explains what to do.