2

I have one enum type which is having items with spaces

     public enum Enum1
    {
        [Description("Test1 Enum")]
        Test1Enum,
        [Description("Test2 Enum")]
        Test2Enum,
        [Description("Test3Enum")]
        Test3Enum, 
    }

   public void TestMethod(string testValue)
     {
        Enum1 stEnum;
        Enum.TryParse(testValue, out stEnum);
        switch (stEnum)
        {
            case ScriptQcConditonEnum.Test1Enum:
                Console.Log("Hi");
                break;
        }
      }

When i using Enum.TryParse(testValue, out stEnum) ,It always returns first element.

 // Currently stEnum returns Test1Enum which is wrong
    Enum.TryParse("Test2 Enum", out stEnum) 
vmb
  • 2,878
  • 15
  • 60
  • 90
  • 1
    What's in `testValue`? It looks at the name of the value, not the description. By that I mean there are no spaces in your enum. – Brandon Feb 15 '17 at 18:18
  • 5
    In all likelihood TryParse is returning false meaning the parse failed and stEnum is the default value, 0, which is TestEnum1. I'm not sure what this DescriptionAttribute is, but I don't think the Enum.Parse/TryParse methods do anything with it. – Mike Zboray Feb 15 '17 at 18:19
  • @Brandon testValue is string. eg : Test1 Enum ..ie same as value i put in [Description] attribute – vmb Feb 15 '17 at 18:21
  • It doesn't compare the `Description` value. It looks at the name – Brandon Feb 15 '17 at 18:44
  • 1
    Also, if using object.TryParse, check the return value (that's why it's a `Try`). `if (! Enum.TryParse(...) { ReportThatItFailed(); }` – Wonko the Sane Feb 15 '17 at 18:57

3 Answers3

4

You can parse Enum from Enum description but you need to retrieve Enum value from description. Please check below example, that retrieve Enum value from Enum description and parse it as you want.

Enum value from Enum description:

public T GetValueFromDescription<T>(string description)
    {
        var type = typeof(T);
        if (!type.IsEnum) throw new InvalidOperationException();
        foreach (var field in type.GetFields())
        {
            var attribute = Attribute.GetCustomAttribute(field,
                typeof(DescriptionAttribute)) as DescriptionAttribute;
            if (attribute != null)
            {
                if (attribute.Description == description)
                    return (T)field.GetValue(null);
            }
            else
            {
                if (field.Name == description)
                    return (T)field.GetValue(null);
            }
        }
        throw new ArgumentException("Not found.", "description");
        // or return default(T);
    }

Example of parse:

Enum.TryParse(GetValueFromDescription<Enum1>("Test2 Enum").ToString(), out stEnum);
csharpbd
  • 3,786
  • 4
  • 23
  • 32
1

Enum.TryParse trys to parse the string based on the enum value not description. If your requirement is to parse based on description you need to use reflection to get the attribute value. How to do this has already been answered in this SO question: Finding an enum value by its Description Attribute

Shane Ray
  • 1,449
  • 1
  • 13
  • 18
  • ..Is any other option other than reflection to solve this issue..Or like any logical approach – vmb Feb 15 '17 at 18:30
  • It depends on your use case. You could try `Enum.TryParse(testValue.Replace(" ", string.Empty), out stEnum);` but that will only match if the description is the same as the value except spaces as in your example. – Shane Ray Feb 15 '17 at 18:31
  • Did this help you solve your problem? Did you find an answer somewhere else? Please mark the answer that helped or add the answer you found elsewhere. Thanks. – Shane Ray Feb 22 '17 at 17:28
0

Based on the idea of @csharpbd, I thought the following approach.

public static T ParseEnum<T>(string valueToParse)
{
    // Check if it is an enumerated
    if (typeof(T).IsEnum)
    {
        // Go through all the enum
        foreach (T item in (T[])Enum.GetValues(typeof(T)))
        {
            System.Reflection.FieldInfo fieldInfo = item.GetType().GetField(item.ToString());

            // Before doing anything else we check that the name match
            if (fieldInfo.Name == valueToParse)
            {
                return item;
            }

            DescriptionAttribute[] descriptionAttributes = (DescriptionAttribute[])fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false);

            // Check if the description matches what we are looking for.
            if (descriptionAttributes.Length > 0 && descriptionAttributes[0].Description == valueToParse)
            {
                return item;
            }
        }

        throw new ArgumentException("Enum cannot be found", valueToParse);
    }
    else
    {
        throw new InvalidOperationException("The object is not an enum");
    }
}

Therefore, you can call him:

Enum1 stEnum = ParseEnum<Enum1>(testValue);
Warger
  • 1
  • 2