Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Use of the Enum Description (With Special Characters) in C#

0.00/5 (No votes)
13 Sep 2014 1  
Can your enums have userfriendly descriptions? How to have enum values with spaces?

Introduction

Can your enums have userfriendly descriptions? How to have enum values with spaces?
What is the use of the enum description (with special characters) in C#?
How can you describe basic convertion extension methods. (Enum.ToDescription(), string.ToEnum<T>())?

Using the Code

Create your enum in your project.

public enum MyEnum1
{
    [DescriptionHelper("[Not selected]")]
    None = 0,
    Video = 1,
    Audio = 2,
    Teletext = 3,
    [DescriptionHelper("DVB Subtitles")]
    DVB_Subtitles = 4,
    ECM = 6,
    Private = 9,
    [DescriptionHelper("AC-3 Audio")]
    AC3_Audio = 10,
    [DescriptionHelper("H.264 Video")]
    H264_Video = 11,
    VBI = 12,
    [DescriptionHelper("AAC Audio")]
    AAC_Audio = 13,
}

Create your attribute class:

namespace EnumSample
{
    public class DescriptionHelperAttribute : Attribute
    {
        public DescriptionHelperAttribute(string description)
        {
            this.Description = description;
        }

        public string Description { get; protected set; }
    }
}

Then include these static extension methods in your code:

namespace EnumSample
{
    public static class MyUtility
    {
        public static T ToEnum<T>(this string s, bool ignoreCase) where T : struct
        {
            Type genericType = typeof(T);
            if (!genericType.IsEnum) return default(T);

            T response;
            if (Enum.TryParse(s, ignoreCase, out response))
            {
                return response;
            }

            Array ary = Enum.GetValues(genericType);
            foreach (T en in ary)
            {
                if ((string.Compare(en.ToString(), s, ignoreCase) == 0) ||
                    (string.Compare((en as Enum).ToDescription(), s, ignoreCase) == 0))
                {
                    return en;
                }
            }

            return default(T);
        }

        public static T ToEnum<T>(this string s) where T : struct
        {
            return s.ToEnum<T>(false);
        }

        public static string[] GetEnumDescriptions<T>() where T : struct
        {
            Type genericType = typeof(T);
            if (!genericType.IsEnum) return new string[0];

            Array ary = Enum.GetValues(genericType);
            string[] strAry = new string[ary.Length];
            int ndx = 0;
            foreach (T en in ary)
            {
                strAry[ndx++] = (en as Enum).ToDescription();
            }
            return strAry;
        }

        public static string ToDescription(this Enum en)
        {
            Type type = en.GetType();

            MemberInfo[] memInfo = type.GetMember(en.ToString());

            if (memInfo != null && memInfo.Length > 0)
            {
                object[] attrs = memInfo[0].GetCustomAttributes(typeof(DescriptionHelperAttribute), false);
                if (attrs != null && attrs.Length > 0)
                {
                    return ((DescriptionHelperAttribute)attrs[0]).Description;
                }
            }

            return en.ToString();
        }
    }
}

Use in the project (Testing):

MyEnum1 en;

// test1
Console.WriteLine();
Console.WriteLine("Test 1) String to enum test...");
Console.WriteLine("   (\"bla bla bla...\").ToEnum<MyEnum1>()");
en = ("bla bla bla...").ToEnum<MyEnum1>();
Console.WriteLine("   \"bla bla bla...\" was not found in MyEnum1! 
However, the result \"{0}\" will be...", default(MyEnum1));
Console.WriteLine("   Result >> Value:\"{0} - {1}\", 
Description:\"{2}\"", (int)en, en.ToString(), en.ToDescription());
Console.WriteLine();

// test2
Console.WriteLine();
Console.WriteLine("Test 2) String to enum test...");
Console.WriteLine("   (\"H.264 Video\").ToEnum<MyEnum1>()");
en = ("H.264 Video").ToEnum<MyEnum1>();
Console.WriteLine("   Result >> Value:\"{0} - {1}\", 
Description:\"{2}\"", (int)en, en.ToString(), en.ToDescription());
Console.WriteLine();

// test3
Console.WriteLine();
Console.WriteLine("Test 3) String to enum test... (Classic 'Enum.Parse' method)");
Console.WriteLine("   (MyEnum1)Enum.Parse(typeof(MyEnum1), \"H.264 Video\")");
Console.WriteLine("   \"H.264 Video\" was not found in MyEnum1! \"H264_Video\" should be...");
Console.WriteLine("   In this example, the classic 'Enum.Parse' method is useless.");
try
{
    en = (MyEnum1)Enum.Parse(typeof(MyEnum1), "H.264 Video");
}
catch (Exception ex)
{
    Console.WriteLine("   Result >> Error[{0:X}] - {1}", ex.HResult, ex.Message);
}
Console.WriteLine();

// test4
Console.WriteLine();
Console.WriteLine("Test 4) GetEnumDescriptions for 'FormWindowState'");
Console.WriteLine("   Result:");
string[] sAry = MyUtility.GetEnumDescriptions<System.Windows.Forms.FormWindowState>();
foreach (string s in sAry)
{
    Console.WriteLine("   >> {0}", s);
}
Console.WriteLine();

This will display:

Test 1) String to enum test...
   ("bla bla bla...").ToEnum<MyEnum1>()
   "bla bla bla..." was not found in MyEnum1! However, the result "None" will be...
   Result >> Value:"0 - None", Description:"[Not selected]"

Test 2) String to enum test...
   ("H.264 Video").ToEnum<MyEnum1>()
   Result >> Value:"11 - H264_Video", Description:"H.264 Video"

Test 3) String to enum test... (Classic 'Enum.Parse' method)
   (MyEnum1)Enum.Parse(typeof(MyEnum1), "H.264 Video")
   "H.264 Video" was not found in MyEnum1! "H264_Video" should be...
   In this example, the classic 'Enum.Parse' method is useless.
   Result >> Error[80070057] - Requested value 'H.264 Video' was not found.

Test 4) GetEnumDescriptions for 'FormWindowState'
   Result:
   >> Normal
   >> Minimized
   >> Maximized

Points of Interest

Why C# doesn't have extension properties? Interesting...

History

  • 14th September, 2014: Initial post

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here