4

So we have our enums setup like this:

[CorrelatedNumeric(0)]
[Description("USD")]
[SequenceNumber(10)]
USD = 247

Basically, another function can provide the string "USD" to me, but not the exact enum because the source of it is Excel and we can't make our users remember the enum values ;) nor would that make much sense.

Is there a way in c# to get from "USD" to 247 from having our enums setup as they are above?

3 Answers 3

16

Would Enum.TryParse() or Enum.Parse() do what you need?

Currency cValue = (Currency) Enum.Parse(typeof(Currency), currencyString); 
Sign up to request clarification or add additional context in comments.

3 Comments

@slandau: That's going based on the enum name, not the attribute value. Is that what you're after? If so, it would probably be best to change the title of your post - I answered assuming you wanted it based on the Description attribute.
Well, they actually are always named the same, so I'll change the title of my post, but thanks for your answer as well :)
Keep in mind that Enum.TryParse "converts the string representation of the name OR NUMERIC VALUE of one or more enumerated constants to an equivalent enumerated object". So if you want user to input "USD" but he inputs "123", it may pass by parsing some other currency if you have one defined as 123.
4

Absolutely - build a Dictionary<string, YourEnumType> by reflection. Just iterate over all the fields in the enum and find the attribute values, and build up the dictionary that way.

You can see how I've done something similar in Unconstrained Melody for the description attribute, in EnumInternals:

// In the static initializer...
ValueToDescriptionMap = new Dictionary<T, string>();
DescriptionToValueMap = new Dictionary<string, T>();
foreach (T value in Values)
{
    string description = GetDescription(value);
    ValueToDescriptionMap[value] = description;
    if (description != null && !DescriptionToValueMap.ContainsKey(description))
    {
        DescriptionToValueMap[description] = value;
    }
}

private static string GetDescription(T value)
{
    FieldInfo field = typeof(T).GetField(value.ToString());
    return field.GetCustomAttributes(typeof(DescriptionAttribute), false)
                .Cast<DescriptionAttribute>()
                .Select(x => x.Description)
                .FirstOrDefault();
}

Just do the same thing for your own attribute type.

1 Comment

+1, that makes much more sense, as it 'parses' based on the description attribute instead of the enum value name, like Enum.Parse() does.
1
 public static object enumValueOf(string description, Type enumType)
 {
      string[] names = Enum.GetNames(enumType);
      foreach (string name in names)
      {
          if (descriptionValueOf((Enum)Enum.Parse(enumType, name)).Equals(description))
           {
               return Enum.Parse(enumType, name);
           }
       }

       throw new ArgumentException("The string is not a description of the specified enum.");
  }

  public static string descriptionValueOf(Enum value)
  {
       FieldInfo fi = value.GetType().GetField(value.ToString());
       DescriptionAttribute[] attributes = (DescriptionAttribute[]) fi.GetCustomAttributes( typeof(DescriptionAttribute), false);
       if (attributes.Length > 0)
       {
             return attributes[0].Description;
       }
       else
       {
            return value.ToString();
       }
  }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.