using System; using System.Collections; using System.Reflection; namespace Ems.BusinessTracker.Common.Linq { #region Class StringEnum /// /// Helper class for working with 'extended' enums using attributes. /// http://www.codeproject.com/KB/cs/stringenum.aspx /// public class StringEnum { #region Instance implementation private Type _enumType; private static Hashtable _stringValues = new Hashtable(); /// /// Creates a new instance. /// /// Enum type. public StringEnum(Type enumType) { if (!enumType.IsEnum) throw new ArgumentException(String.Format("Supplied type must be an Enum. Type was {0}", enumType.ToString())); _enumType = enumType; } /// /// Gets the string value associated with the given enum value. /// /// Name of the enum value. /// String Value public string GetStringValue(string valueName) { Enum enumType; string stringValue = null; try { enumType = (Enum)Enum.Parse(_enumType, valueName); stringValue = GetStringValue(enumType); } catch (Exception) { }//Swallow! return stringValue; } /// /// Gets the string values associated with the enum. /// /// String value array public Array GetStringValues() { ArrayList values = new ArrayList(); //Look for our string value associated with fields in this enum foreach (FieldInfo fi in _enumType.GetFields()) { //Check for our custom attribute StringValueAttribute[] attrs = fi.GetCustomAttributes(typeof(StringValueAttribute), false) as StringValueAttribute[]; if (attrs.Length > 0) values.Add(attrs[0].Value); } return values.ToArray(); } /// /// Gets the values as a 'bindable' list datasource. /// /// IList for data binding public IList GetListValues() { Type underlyingType = Enum.GetUnderlyingType(_enumType); ArrayList values = new ArrayList(); //Look for our string value associated with fields in this enum foreach (FieldInfo fi in _enumType.GetFields()) { //Check for our custom attribute StringValueAttribute[] attrs = fi.GetCustomAttributes(typeof(StringValueAttribute), false) as StringValueAttribute[]; if (attrs.Length > 0) values.Add(new DictionaryEntry(Convert.ChangeType(Enum.Parse(_enumType, fi.Name), underlyingType), attrs[0].Value)); } return values; } /// /// Return the existence of the given string value within the enum. /// /// String value. /// Existence of the string value public bool IsStringDefined(string stringValue) { return Parse(_enumType, stringValue) != null; } /// /// Return the existence of the given string value within the enum. /// /// String value. /// Denotes whether to conduct a case-insensitive match on the supplied string value /// Existence of the string value public bool IsStringDefined(string stringValue, bool ignoreCase) { return Parse(_enumType, stringValue, ignoreCase) != null; } /// /// Gets the underlying enum type for this instance. /// /// public Type EnumType { get { return _enumType; } } #endregion #region Static implementation /// /// Gets a string value for a particular enum value. /// /// Value. /// String Value associated via a attribute, or null if not found. public static string GetStringValue(Enum value) { string output = null; Type type = value.GetType(); if (_stringValues.ContainsKey(value)) output = (_stringValues[value] as StringValueAttribute).Value; else { //Look for our 'StringValueAttribute' in the field's custom attributes FieldInfo fi = type.GetField(value.ToString()); StringValueAttribute[] attrs = fi.GetCustomAttributes(typeof(StringValueAttribute), false) as StringValueAttribute[]; if (attrs.Length > 0) { _stringValues.Add(value, attrs[0]); output = attrs[0].Value; } } return output; } /// /// Parses the supplied enum and string value to find an associated enum value (case sensitive). /// /// Type. /// String value. /// Enum value associated with the string value, or null if not found. public static object Parse(Type type, string stringValue) { return Parse(type, stringValue, false); } /// /// Parses the supplied enum and string value to find an associated enum value. /// /// Type. /// String value. /// Denotes whether to conduct a case-insensitive match on the supplied string value /// Enum value associated with the string value, or null if not found. public static object Parse(Type type, string stringValue, bool ignoreCase) { object output = null; string enumStringValue = null; if (!type.IsEnum) throw new ArgumentException(String.Format("Supplied type must be an Enum. Type was {0}", type.ToString())); //Look for our string value associated with fields in this enum foreach (FieldInfo fi in type.GetFields()) { //Check for our custom attribute StringValueAttribute[] attrs = fi.GetCustomAttributes(typeof(StringValueAttribute), false) as StringValueAttribute[]; if (attrs.Length > 0) enumStringValue = attrs[0].Value; //Check for equality then select actual enum value. if (string.Compare(enumStringValue, stringValue, ignoreCase) == 0) { output = Enum.Parse(type, fi.Name); break; } } return output; } /// /// Return the existence of the given string value within the enum. /// /// String value. /// Type of enum /// Existence of the string value public static bool IsStringDefined(Type enumType, string stringValue) { return Parse(enumType, stringValue) != null; } /// /// Return the existence of the given string value within the enum. /// /// String value. /// Type of enum /// Denotes whether to conduct a case-insensitive match on the supplied string value /// Existence of the string value public static bool IsStringDefined(Type enumType, string stringValue, bool ignoreCase) { return Parse(enumType, stringValue, ignoreCase) != null; } #endregion } #endregion #region Class StringValueAttribute /// /// Simple attribute class for storing String Values /// public class StringValueAttribute : Attribute { private string _value; /// /// Creates a new instance. /// /// Value. public StringValueAttribute(string value) { _value = value; } /// /// Gets the value. /// /// public string Value { get { return _value; } } } #endregion }