Matias Cicero
Matias Cicero

Reputation: 26301

Converting enum to string (and viceversa) using annotations

Usually, when I find myself in need to convert an enum to a string or viceversa, I generally take advantage of the Description Attribute.

For instance, If I had the following enum:

public enum QueryOperations
{
     [Description("eq")]
     Equals,

     [Description("gt")]
     GreaterThan,

     [Description("lt")]
     LessThan
}

I would convert QueryOperations.GreaterThan to a string using its DescriptionAttribute's value, i.e., it would be converted to "gt".

In the same way, If i was to convert "lt" to QueryOperations, I would end up with QueryOperations.LessThan.

I really like this approach and never failed me so far. I think it is flexible, easy to understand and it is decoupled from the enum's value names.

However, quoting MSDN, a DescriptionAttribute:

[...] Specifies a description for a property or event.

An example is shown:

[Description("The image associated with the control"),Category("Appearance")] 
public Image MyImage { get; set; }

This troubles me because it seems that the purpose of the DescriptionAttribute is semantically different to what I use it for.

Using Attributes to convert an enum is not a silly nor crazy idea, so my question is:

Is it there an attribute specifically designed for this case?

Something like:

public enum QueryOperations
{
    [StringRepresentation("eq")]
    Equals,
    //...
}

Upvotes: 0

Views: 1630

Answers (2)

tsacodes
tsacodes

Reputation: 360

I like to use extension methods. This article http://weblogs.asp.net/grantbarrington/enumhelper-getting-a-friendly-description-from-an-enum covers the topic more in depth

here's a quick peek at the extension method:

 public static class EnumHelper
    {
        /// <summary>
        /// Retrieve the description on the enum, e.g.
        /// [Description("Bright Pink")]
        /// BrightPink = 2,
        /// Then when you pass in the enum, it will retrieve the description
        /// </summary>
        /// <param name="en">The Enumeration</param>
        /// <returns>A string representing the friendly name</returns>
        public static string GetDescription(Enum en)
        {
            Type type = en.GetType();

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

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

                if (attrs != null && attrs.Length > 0)
                {
                    return ((DescriptionAttribute)attrs[0]).Description;
                }
            }

            return en.ToString();
        }

    }

You would get the description like so:

MyEnum.EnumsValue.GetDescription();

Going back the other way, you could use Parse or TryParse built in the .NET framework:

//Parse
MyEnum enumValue = (MyEnum) Enum.Parse(typeof(MyEnum), enumValueString);

//TryParse
MyEnum enumValue;
Enum.TryParse(enumValueString, out enumValue));

Upvotes: 1

DrewJordan
DrewJordan

Reputation: 5314

Short answer is no, there's not anything built in.

I think if the use case you presented is typical of what you need to do, you're better off creating a custom attribute. The Description attribute can be used in the way you're using it, but as you already mentioned, it's really meant to be a human-readable description.

For instance, you could do something like this:

    public class StringRepresentationAttribute : Attribute
    {
        public StringRepresentationAttribute(string stringRep)
        {
            this._stringRep = stringRep;
        }

        public string StringRepresentation { get { return _stringRep; } }

        private readonly string _stringRep;

        public override string ToString()
        {
            return StringRepresentation;
        }
    }

Then have something like this as an extension method:

public static string GetStringRepresentation(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(StringRepresentationAttribute), false);

                if (attrs != null && attrs.Length > 0)
                {
                    return ((StringRepresentationAttribute)attrs[0]).StringRepresentation;
                }
            }

            return en.ToString();
        }

The your enum becomes:

public enum QueryOperations
{
     [StringRepresentation("eq")]
     Equals,

     [StringRepresentation("gt")]
     GreaterThan,

     [StringRepresentation("lt")]
     LessThan
}

And now you can:

string operatorAsString = QueryOperations.LessThan.GetStringRepresentation();

Upvotes: 2

Related Questions