Click here to Skip to main content
Click here to Skip to main content

Using Attributes, Reflection and Generics To Increase The Usability Of Enums

By , 22 Aug 2010
Rate this:
Please Sign up or sign in to vote.

Introduction

This article explains a solution that I came up with to make the most of the enums we were using in one of our systems beings developed. The solution makes use of custom attributes, reflection and generics to maximise our use of enums.

Background

At work we are busy doing a new project that makes use of a lot of enums, of different types. As everyone know, enums can
make life much easier when it comes to coding, and this project was no different.

During the development the need to associate additional data with the enums became clear. This article will describe the methods we implemented to overcome this obstacle.

Building Blocks of the Solution

Most people have seen the examples of giving a “EnumDescription” attribute to each anum value, which is then reflected to return a human-friendly description of the required enum value.

An example of this scenario would be:

public enum Institution
{
    [EnumDescription(“Bank A”)]
     BankA,
  
    [EnumDescription (“Shop B”)]
     ShopB,
    [Description(“Library C”)]
     LibraryC
}

Our solution is based on a similar concept, but expanded it to include not only description on the attribute, but other needed properties as well. In our project we created several new custom attributes, that can be used to decorate the enums as needed, depending on the data we need to associate with it.

For example:

[AttributeUsage(AttributeTargets.Field, AllowMultiple = false)]
public sealed class InstituteAttribute: Attribute
{
    public InstituteAttribute(string Desc, string Phone)
    {
        Description = Desc;
        Telephone=Phone;
    }              
    public string Description {get;set;}
    public string Telephone {get;set;}
}
[AttributeUsage(AttributeTargets.Field, AllowMultiple = false)]
public sealed class AddressAttribute: Attribute
{
     public AddressAttribute (string Add1, string Add2, string City, string ZipCode)
     {
         this.Address1 = Add1;
         this.Address2 = Add2;
         this.City = City;
         this.ZipCode = ZipCode;
     }              
     public string Address1 {get;set;}
     public string Address2 {get;set;}
     public string City {get;set;}
     public string ZipCode {get;set;}
}

To get the values of these attributes, and it’s properties we can easily apply the same concept we use in “EnumDescription” situation, but this is not very flexible, since we have to know what type we are working on, and which properties exist.

Usage example of these new attributes:

public enum Institution
{
    [Institute (“Bank A”,  ”(856) 745-1546”)]
    [Address(“123 Street”, “Some town”, “Some City” , ”1452”)] 
     BankA,
  
    [Institute (“Shop B”,  “(012) 154-1456”)]
     ShopB,
    
    [Institute (“Library C”,  “(123) 147-4567”)]
     LibraryC
}

To make use of this information we created a helper extension method that can be used to reflect on any type of attribute, to get any property on that attribute. Below is the extension method to solve this issue.

Using the Code

Short summary of what the extension method below does:

/// <summary>
/// Use this extension method to obtain any property in an attribute used to decorate the fields of an Enum.
/// </summary>
/// <typeparam name="T">Type of attribute containing the wanted properties</typeparam>
/// <param name="value">This will be the Enum value</param>
/// <param name="AttributeProperty">The property of the specified attribute that must be returned.</param>
/// <returns>The property value specified</returns>
public static string GetPropertyValue<T>(this Enum value, string AttributeProperty)
{
    //Get the enum value
    FieldInfo fi = value.GetType().GetField(value.ToString());
    
    T[] atts = fi.GetCustomAttributes(typeof(T), false) as T[];
    //if there is any attributes of the specified type
    if (atts.Length == 0)
    return string.Empty;
 
    //find propertyname
    PropertyInfo pi = atts[0].GetType().GetProperty(AttributeProperty);
    if (pi == null)
    throw new ArgumentException(String.Format("{0} is not a valid property name.", AttributeProperty));
 
    //return value of property
    return pi.GetValue(atts[0],null).ToString();
}

Now that we have this extension method on place, we can easily get the data we require from the enums.

Example:

string shopPhone = Institution.ShopB.GetPropertyValue<InstituteAttribute>(“Telephone”);

The above statement will call the GetPropertyValue extension method on the ShopB enum value, and return the value of the “Telephone” property in the “Institute” attribute used to decorate enum value ShopB.

Feedback

I hope some of you find this helpful, and please do not hesitate to leave any feedback, improvements, or other. Also remember to please vote.

Thanks!

History

2010-08-16 - Version 1.0

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Dieter Deysel
Software Developer South African Reserve Bank
South Africa South Africa
I am currently employed by the South African Reserve Bank where my main focus is Windows Application Development in C#.
 
I enjoy experimenting with new technologies, reading, watching movies and relaxing with friends.

Comments and Discussions

 
GeneralReason for my vote of 5 Nice post PinmemberShahriar Iqbal Chowdhury10-Feb-11 10:00 
GeneralI don't have the ability to edit your tip/trick, but you mig... Pinprotectoraspdotnetdev20-Aug-10 13:40 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web04 | 2.8.140415.2 | Last Updated 23 Aug 2010
Article Copyright 2010 by Dieter Deysel
Everything else Copyright © CodeProject, 1999-2014
Terms of Use
Layout: fixed | fluid