using System;
using System.ComponentModel;
namespace ConsoleApplication1
{
public enum ThreadPriority
{
[Description("Highest")]
Highest,
[Description("Above Normal")]
AboveNormal,
[Description("Normal")]
Normal,
[Description("Below Normal")]
BelowNormal,
[Description("Lowest")]
Lowest
}
class Program
{
static void Main(string[] args)
{
ThreadPriority threadPriority = EnumHelper<ThreadPriority>.Parse("AboveNormal");
System.Diagnostics.Debug.Assert(threadPriority == ThreadPriority.AboveNormal);
string description = EnumHelper<ThreadPriority>.EnumValueDescription(threadPriority);
System.Diagnostics.Debug.Assert(description.Equals("Above Normal"));
threadPriority = EnumHelper<ThreadPriority>.ParseOrDescriptionMatch("Below Normal", ThreadPriority.Normal);
System.Diagnostics.Debug.Assert(threadPriority == ThreadPriority.BelowNormal);
if (!EnumHelper<ThreadPriority>.TryParse("Highest", out threadPriority))
{
System.Diagnostics.Debug.Fail("TryParse expected to succeed");
}
System.Diagnostics.Debug.Assert(threadPriority == ThreadPriority.Highest);
if (EnumHelper<ThreadPriority>.TryParse("Foo Bar", out threadPriority))
{
System.Diagnostics.Debug.Fail("TryParse expected to fail");
}
}
}
public static class EnumHelper<T>
where T : struct, IComparable, IFormattable, IConvertible
{
///
/// Static constructor to ensure T is an enum
///
static EnumHelper()
{
if (!typeof(T).IsEnum)
{
throw new ArgumentException("Type parameter must be an enum");
}
}
/// <summary>
/// Converts the string representation of the name or numeric value of one or
/// more enumerated constants to an equivalent enumerated object.
/// </summary>
/// <param name="value">A string containing the name or value to convert.</param>
/// <returns>An object of type T whose value is represented by value.</returns>
/// <exception cref="System.ArgumentNullException">value is null</exception>
/// <exception cref="System.ArgumentException">value is either an empty string or
/// only contains white space. -or- value is a name, but not one of the named
/// constants defined for the enumeration.
///</exception>
public static T Parse(string value)
{
return (T)Enum.Parse(typeof(T), value);
}
///
/// Converts the string representation of the name or numeric value of one or more enumerated constants to an equivalent enumerated object.
///
/// A string containing the name or value to convert.
/// When this method returns, contains the object of type T whose
/// value is represented by the value, if the conversion succeeded, or the first
/// value in the enum if conversion failed. This parameter is passed uninitialized.
/// true if value was converted successfully; otherwise, false.
public static bool TryParse(object value, out T returnValue)
{
Type underlyingType = Enum.GetUnderlyingType(typeof(T));
bool supportedType = (value is string || value.GetType().Equals(underlyingType));
if (supportedType && Enum.IsDefined(typeof(T), value))
{
//direct string or underlying type match
returnValue = Parse(value.ToString());
return true;
}
else if (Enum.IsDefined(typeof(T), Convert.ChangeType(value, underlyingType))) // May throw overflow exception. E.g. long.MaxValue to Int32
{
//underlying numeric type match after type conversion
returnValue = (T)Enum.Parse(typeof(T), value.ToString());
return true;
}
else
{
//Default to the first item from the enum
string[] values = Enum.GetNames(typeof(T));
returnValue = (T)Enum.Parse(typeof(T), values[0], true);
//default(T) won't work for all enums.
//E.g. if the underlying type for the enum is int default(T) will always return 0, for which there might not be a value.
}
return false;
}
/// <summary>
/// Attempt to read the Description Attribute
/// </summary>
/// <param name="e">The enum value to read the description from</param>
/// <returns>The description value for the enum, otherwise the enum value converted to a string.</returns>
public static string EnumValueDescription(T e)
{
System.Reflection.FieldInfo EnumInfo = e.GetType().GetField(e.ToString());
System.ComponentModel.DescriptionAttribute[] enumAttributes =
(System.ComponentModel.DescriptionAttribute[])
EnumInfo.GetCustomAttributes(typeof(System.ComponentModel.DescriptionAttribute), false);
if (enumAttributes.Length > 0)
{
return enumAttributes[0].Description;
}
return e.ToString();
}
/// <summary>
/// Converts the string representation of the name or numeric value of one or
/// more enumerated constants to an equivalent enumerated object.
/// If a direct match isn't found a match will be attempted on the description attributes.
/// </summary>
/// <param name="value"></param>
/// <param name="defaultValue"></param>
/// <returns></returns>
public static T ParseOrDescriptionMatch(string value, T defaultValue)
{
Type type = typeof(T);
try
{
return Parse(value);
}
catch (Exception)
{
//Try Description Matching
string[] names = Enum.GetNames(type);
foreach (string name in names)
{
T nameEnum = Parse(name);
string nameEnumValue = EnumValueDescription(nameEnum);
if (nameEnumValue == value)
{
return nameEnum;
}
}
return defaultValue;
}
}
}
}