C# Using Extended Attribute Information on Objects

Update 5/26/2014 : Added Enum Extension to Extract Custom Attribute.

I use this trick in .Net to extensively Trojan Horse extra meta type information on any object. At run time I reflect off of the object and extract this information which was placed on it. Below I show how to do it on an enum using a built in attribute in .Net and secondly I show how to create your own custom attribute. Note: in the example is an enum, but one can decorate any object with the attribute.

Single Attribute Values

The first way which will be shown is done using C#’s description attribute found in the System.ComponentModel namespace and does not require any special coding such as creating a class definition for the attribute. The second way shows a more robust custom attribute which has more specialized information.

Step 1 Include these namespaces:

using System.Reflection;
using System.ComponentModel;

Step 2 Decorate the enums with the Description Attribute

public enum EPortalErrors
  [Description("Internal programming error")]
  [Description("Invalid request Xml: Reset XSLT.")]

Step 3 Create a static method to divine the attribute description

/// <summary>If an attribute such as is on an enumeration exists, this will return that
/// information</summary>
/// <param name="value">The object which has the attribute.</param>
/// <returns>The description string of the attribute or string.empty</returns>
public static string GetAttributeDescription( object value )
    string retVal = string.Empty;
        FieldInfo fieldInfo = value.GetType().GetField(value.ToString());

        DescriptionAttribute[] attributes =
           (typeof(DescriptionAttribute), false);

        retVal = ( ( attributes.Length > 0 ) ? attributes[0].Description : value.ToString() );
    catch (NullReferenceException)
     //Occurs when we attempt to get description of an enum value that does not exist
        if (string.IsNullOrEmpty(retVal))
            retVal = "Unknown";

    return retVal;

Step 4 Call GetAttributeDescription with the enum in hand and we will get the extended text. Done…

Multiple Attribute Values

That first method is is nice for basic information, but what if one needs more information? That can be done by writing a custom attribute information extraction class. We will start at step 2 from above:

Step 2 Determine what items should be on the attribute and create an attribute name. In the below example we want to decorate the enum with three integers and another enum. This extended information will allow for other processing to occur which is dependant on that info. Our attribute name is DatabaseConnection which will mirror our attribute extraction class

public enum EActivities

    /// <summary>We need to inform the DAL that the primary keys are 1,2,3 and
    /// that we only want one column</summary>
   [DatabaseConnection(1,2,3, DatabaseConnectionAttribute.Columns.OneColumn)]

Step 3 Create a static method to divine the attribute description for DatabaseConnection. Note there is other activities/properties that are shown, for the consumer can get the extended int info in a list. Note also we have to decorate the class with an attribute to let the system know that this class will be used as an attribute

/// <summary>When using Enums for exceptions this attribute provides more information
/// to describe the enumeration such as target fields and primary keys.</summary>
public class DatabaseConnectionAttribute : Attribute

    #region Construction    

    /// <summary>Used to specify the needed columns.</summary>
    public enum Columns : int
        OneColumn = 1,
        TwoColumns = 2,
        ThreeColumns = 3,
        FourColumns = 4,
        FiveColumns = 5,
        SixColumns = 6

    /// <summary>Allow a consumer to specify an attribute with for data items.</summary>
    public DatabaseConnectionAttribute(int pkey1, int pkey2, int pkey3, DatabaseConnectionAttribute.Columns columns)
        _Columns = columns;

    #region Properties
    /// <summary>To total number of columns to extract from the database.</summary>
    public DatabaseConnectionAttribute.Columns ColumnsNeeded
        get { return _Columns; }

    /// <summary>Retrieves the list of primary keys.</summary>
    public List<int> PrimaryKeys
        get { return pkeys; }


    #region Exposed Static Functionality

    /// <summary>This method will peer into an enum and extract this class if it exists.</summary>
    /// <param name="enumItem">The enumeration which contains the DatabaseConnectionAttribute.</param>
    /// <returns>The current object or null</returns>
    public static DatabaseConnectionAttribute ExtractAttribute(object enumItem)
        DatabaseConnectionAttribute retVal = null;

            FieldInfo fieldInfo = enumItem.GetType().GetField(enumItem.ToString());
            DatabaseConnectionAttribute[] attributes =
                (typeof(DatabaseConnectionAttribute), false);

            if (attributes != null)
                if (attributes.Length > 0)
                    retVal = attributes[0];
        catch (NullReferenceException)
            //Occurs when we attempt to get description of an enum value that does not exist

        return retVal;

    #region Variables
    /// <summary>Holds the primary key information.</summary>
    List<int> pkeys = new List<int>();    

    /// <summary>What columns are required by the user.</summary>
    private DatabaseConnectionAttribute.Columns _Columns;


Step 4 Now by calling the static ExtractAttribute we are returned an object that has all of the information off of the enum. Quite handy.


Update: Extracting Custom Attribute using a Generic Extension.

Use this code to extract your custom extension. In the below example we use the custom extension to get the custom attribute, of the enum defined above and its custom attribute.

DatabaseConnectionAttribute custAttr = 

               .ExtractAttribute<DatabaseConnectionAttribute, EActivities>();

Extension Method Code

/// <summary>
/// If an enum has a custom attrbute, this will returrn that attribute or null.
/// </summary>
/// <typeparam name="TCustomAttr">The type of the `custom attribute` to extract from the enum.</typeparam>
/// <typeparam name="TEnumItance">The enum currently being viewed..</typeparam>
/// <param name="instance">The instance.</param>
/// <returns>The custom attribute (TCustomAttr) or null</returns>
public static TCustomAttr ExtractAttribute<TCustomAttr, TEnum>(this TEnum instance)
    if (instance != null)
            FieldInfo fieldInfo = instance.GetType()

            var attributes = fieldInfo.GetCustomAttributes(typeof(TCustomAttr), false)

            if (attributes.Any())
                return (TCustomAttr)attributes[0];

        catch (Exception)

    return default(TCustomAttr);


  1. Werner van Aswegen says:

    Thank you, thank you, thank you so much.

    This was exactly what I was looking for.

    I was working on a piece of code where several dropdown boxes had to be populated from values that were linked to some enums. I couldn’t just use the enum value name (doesn’t make for good english having names such as “MyEnumValue”) and other approaches involved functions that mapped string representations to enum values, the downside being that if you added more values to the enum, you had to manually change the function to map a new string representation. Less than ideal.

    Now I have a function that takes a dropdown list and an enum as arguments and adds list items to the dropdown using the code in step 3 of Single Attribute Values.


    Thank you again.

  2. domoii says:

    This is exactly what I was looking for too! It never crossed my mind to implement this technique, but it works perfectly. Thank you!

  3. j2associates says:

    Thank you, very helpful! One way to check for invalid enum values is as follows:

    if (Enum.IsDefined(typeof(MyEnumType), value)) {
    // Do your work here.
    else {
    throw new ArgumentException(string.Format(“Invalid enum value ‘{0}’.”, value));

  4. PzD says:

    All that stuff (specially the extraction methods) can be greatly improved using extension methods/generics.

    I’m using this to persist enum values to database using understandable string codes instead of underlying integers.

Leave a Reply