public class StringEnumMark
{
#region Instance implementation
private Type enumType;
private static Dictionary<Enum,StringValueAttribute> stringValuePairs = new Dictionary<Enum,StringValueAttribute>();
public Type EnumType
{
get { return this.enumType; }
}
public StringEnumMark(Type enumType)
{
if (!enumType.IsEnum)
throw new ArgumentException(String.Format("Supplied type must be an Enum. Type was {0}", enumType.ToString()));
this.enumType = enumType;
}
public string GetStringValue(string enumItemName)
{
Enum enumItemType;
string stringValue = null;
try
{
enumItemType = (Enum)Enum.Parse(enumType, enumItemName);
stringValue = GetStringValue(enumItemType);
}
catch (Exception) { }//Swallow!
return stringValue;
}
public string[] GetStringValues()
{
List<string> values = new List<string>();
FieldInfo[] filedInfos = this.enumType.GetFields();
//Look for our string value associated with fields in this enum
foreach (FieldInfo fi in filedInfos)
{
//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();
}
public List<KeyValuePair<int,string>> GetEnumUnderlyingValuePairs()
{
Type underlyingType = Enum.GetUnderlyingType(this.enumType);
List<KeyValuePair<int, string>> values = new List<KeyValuePair<int, string>>();
FieldInfo[] filedInfos = this.enumType.GetFields();
//Look for our string value associated with fields in this enum
foreach (FieldInfo fi in filedInfos)
{
//Check for our custom attribute
StringValueAttribute[] attrs = fi.GetCustomAttributes(typeof(StringValueAttribute), false) as StringValueAttribute[];
if (attrs.Length > 0)
{
object enumvalue = Enum.Parse(this.enumType, fi.Name);
object changed = Convert.ChangeType(enumvalue, underlyingType);
values.Add(new KeyValuePair<int,string>((int)changed, attrs[0].Value));
}
}
return values;
}
public bool IsStringDefined(string stringValue)
{
return Parse(this.enumType, stringValue) != null;
}
public bool IsStringDefined(string stringValue, bool ignoreCase)
{
return Parse(this.enumType, stringValue, ignoreCase) != null;
}
#endregion
#region Static implementation
public static string GetStringValue(Enum valueOfEnumItem)
{
string output = null;
Type type = valueOfEnumItem.GetType();
if (stringValuePairs.ContainsKey(valueOfEnumItem))
output = (stringValuePairs[valueOfEnumItem] as StringValueAttribute).Value;
else
{
//Look for our 'StringValueAttribute' in the field's custom attributes
FieldInfo fi = type.GetField(valueOfEnumItem.ToString());
StringValueAttribute[] attrs = fi.GetCustomAttributes(typeof(StringValueAttribute), false) as StringValueAttribute[];
if (attrs.Length > 0)
{
stringValuePairs.Add(valueOfEnumItem, attrs[0]);
output = attrs[0].Value;
}
}
return output;
}
public static T GetEnumByString<T>(string key, T defaultValue)
{
if (!typeof(T).IsSubclassOf(typeof(Enum)))
{
#if DEBUG
throw new ArgumentException(typeof(T).FullName + " is not an enum type.");
#else
return defaultValue;
#endif
}
if (string.IsNullOrEmpty(key))
return defaultValue;
Array arr = Enum.GetValues(typeof(T));
for (int i = 0; i < arr.Length; i++)
{
if (key.Equals(StringEnumMark.GetStringValue((Enum)arr.GetValue(i)), StringComparison.CurrentCultureIgnoreCase))
return (T)arr.GetValue(i);
}
return defaultValue;
}
private static object Parse(Type type, string stringValue)
{
return Parse(type, stringValue, false);
}
private 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()));
FieldInfo[] fieldInfos = type.GetFields();
//Look for our string value associated with fields in this enum
foreach (FieldInfo fi in fieldInfos)
{
//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;
}
public static bool IsStringDefined(Type enumType, string stringValue)
{
return Parse(enumType, stringValue) != null;
}
public static bool IsStringDefined(Type enumType, string stringValue, bool ignoreCase)
{
return Parse(enumType, stringValue, ignoreCase) != null;
}
#endregion
}
public class StringValueAttribute : Attribute
{
private string value;
public StringValueAttribute(string value)
{
this.value = value;
}
public string Value
{
get { return value; }
}
}