RSS

Get desired Attribute of any Enum

24 Sep

A very interesting feature that I was missing is to get a specific attribute that is set on an enum.

public static T GetAttribute<T>(this Enum enumObj) where T : Attribute
{
    FieldInfo fieldInfo = enumObj.GetType().GetField(enumObj.ToString());

    if (fieldInfo == null)
        throw new InvalidOperationException("The value "  + enumObj +
                        " ist not defined as a member of the enum" + enumObj.GetType() + ".");

    object[] attribArray = fieldInfo.GetCustomAttributes(typeof(T), false);

    if (attribArray.Length == 0)
        throw new InvalidOperationException(typeof(T) + " ist not an attribute of " +
                        enumObj.GetType());

    try
    {
        return (T)Convert.ChangeType(attribArray[0], typeof(T));
    }
    catch (System.Exception)
    {
        throw new InvalidOperationException("Cannot cast " + attribArray[0].GetType() + " to " +
                        typeof(T) + ". Please specify the generic parameter to its correct type.");
    }
}

This piece can be used as en extension method on every enum. As generic parameter T you should use the type of the attribute you want to get from the enum.

Note
* The attribute you want to get has to be set on the enum.
* You should always be precise with the type of generic parameter T, to get exactly the Attribute you desire.
* On enums with the Flag attribute set, this method will not work everytime.

Example: By passing “Attribute” as parameter T you will get a InvalidCastException if the DescriptionAttribute is set. It has also no sense to pass “Attribute” because then, in the best case, you will get the first attribute that is set on the enum.

Example:

public enum Month
{
    [Description("1st month of the year")]
    January,
    [Description("2dn month of the year")]
    February,
    [Description("3rd month of the year")]
    March,
    [...]
}

Reading the description from the value is done following:

Month m = Month.January;
string s = m.GetAttribute<DescriptionAttribute>().Description;

The value of variable s is then “1st month of the year”.

Flag enum

Example of an enum with flag attribute set:

[Flags]
public enum Month
{
    [Description("1st month of the year")]
    January= 0x1,
    [Description("2dn month of the year")]
    February= 0x2,
    [Description("3rd month of the year")]
    March= 0x4,
    [Description("4th month of the year")]
    April= 0x8,
    [Description("5th month of the year")]
    May= 0x10,
    [Description("6th month of the year")]
    June= 0x20,
    [...]
    [Description("12th month of the year")]
    December= 0x1000,
    [Description("All months in spring")]
    Spring = March | April | May | June,
    [Description("All months in winter")]
    Spring = December | January | February | March,
}

Please be avare of using flags on enums when you call GetArrtibute().
The problem is of its internal nature. The values the fields in the flag enum has to be of power of 2.
Therefore considering the example above, if you set flag Jannuary | February the resulting value is 3, but 3 is not defined as a value in the bitfield.
Therefore it doesn’t exist a description for value 3.

An example that works:

Month m= Month.Spring;
string s = m.GetAttribute<DescriptionAttribute>().Description;

The value of string s is:
All months in spring

Another example that won’t work

Months m = Month.Spring | Month.Winter;
string s= m.GetAttribute<DescriptionAttribute>().Description;

Here we will get an InvalidOperationException saying.
The value “Spring, Winter” ist not defined as a member of the enum Month.

Advertisements
 
2 Comments

Posted by on September 24, 2010 in C-Sharp

 

Tags: ,

2 responses to “Get desired Attribute of any Enum

  1. shoe sale

    October 19, 2010 at 23:20

    Excellent post. Thanks.

     
  2. sales tips

    October 20, 2010 at 11:01

    I really appreciate your help, it is very useful for me,you will get good grades!

     

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: