This is an advanced sequel to C#: Enums and Strings Are Friends. One of particularly interesting features of an enum is the possibility of extending its values with attributes.

public enum Digits
These values can be obtained using .NET reflection mechanism. .NET already defines a lot of useful attributes such as Description, DisplayName, DefaultValue.

On top of that you are able to derive your custom attributes from the Attribute class. By adding properties to this class you can attach a plethora of information to each value of an enum.
public class RomanAttribute : Attribute
    private readonly string _digit;

    public string Digit
        get { return _digit; }

    public RomanAttribute(string title)  // url is a positional parameter
        _digit = title;
Wouldn't it be nice if we could read value of any property of any attribute straight off enum value? The problem with this concept is ... properties of different attributes have different names. For example: DescriptionAttribute has property named Description, and DisplayNameAttribute has property named DisplayName.

Luckily we live in the age of generics and reflections. So reading these properties no longer requires hard coded attribute type and target property. You can simply pass attribute type, property type, property name and enum to a function and let reflection do its business.

// Read [Description] attribute.
Enum e = Days.Sat;
string s = e.GetAttributeProperty<DescriptionAttribute, string>("Description");
Console.WriteLine("Description is {0}", s);
// Read [DisplayName ] attribute.
s = e.GetAttributeProperty<DisplayNameAttribute, string>("DisplayName");
Console.WriteLine("Display name is {0}", s);
// Find enum value based on [Description].
Enum ef = e.FindEnumValueByAttributeProperty<DescriptionAttribute, string>("Description","Friday");
All that is left is to write these two conversion functions.
public static class EnumEx
    #region Enum Extensions
    public static PT GetAttributeProperty<AT, PT>(this Enum this_, string propertyName)
        where AT : Attribute
        where PT : class
        // First get all attributes of type A.
        AT[] attributes = 
            (this_.GetType().GetField(this_.ToString())).GetCustomAttributes(typeof(AT), false) as AT[];

        if (attributes == null || attributes.Length == 0) // Null or can't cast?
            return null;
        { // We have something.
            AT a = attributes[0];
            PropertyInfo pi = a.GetType().GetProperty(propertyName);
            if (pi != null)
                PT result = pi.GetValue(a, null) as PT;
                return result;
                return null;

    public static Enum FindEnumValueByAttributeProperty<AT, PT>(this Enum this_, string propertyName, PT propertyValue)
        where AT : Attribute
        where PT : class, IComparable
        // First get all enum values.
        Array enums = Enum.GetValues(this_.GetType());
        foreach (Enum e in enums)
            PT p = e.GetAttributeProperty<AT, PT>(propertyName);

            if (p!=null && p.Equals(propertyValue))
                return e;
        return null;
    #endregion // Enum Extensions
UPDATE: It seems like the usage of < and > symbols in code corrupted the listings. Fixed it.

1 comment(s) :

UPDATE: It seems like the usage of larger then and smaller then symbols in code corrupted the listings. Fixed it.

2:47 AM  

Newer Post Older Post Home

Blogger Syntax Highliter