Wednesday, September 10, 2008

Enum Parsing

I was getting so frustrated with writing this
ViewMode viewType = (ViewMode)Enum.Parse(typeof(ViewMode), value);

all the time, so I created a class so I can do

ViewMode viewType = EnumParser.Parse<ViewMode>(value);

but the came along extension methods and now we can then do

ViewMode viewType = value.ParseEnum<ViewMode>();

then lastly wouldn't it be cool to have the default value if you can't parse it?

ViewMode viewType = value.GetEnumOrDefault<ViewMode>(ViewMode.None);

so here is the class. There is also some goodies so that you can decorate your enum's with attributes and then GetDescription to have a friendly version for them!

/// <summary>
///
Helpful helper class for all things with enumerations
/// </summary>
public static class EnumParser
{
/// <summary>
///
Parses the specified enum value - ignoring case.
/// </summary>
/// <param name="enumValue">
The enum value.</param>
/// <returns></returns>
[SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter")]
public static T Parse<T>(string enumValue)
{
return Parse<T>(enumValue, true);
}

/// <summary>
///
Parses the specified enum value.
/// </summary>
/// <param name="enumValue">
The enum value.</param>
/// <param name="ignoreCase">
if set to <c>true</c> [ignore case].</param>
/// <returns></returns>
[SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter")]
public static T Parse<T>(string enumValue, bool ignoreCase)
{
if (string.IsNullOrEmpty(enumValue))
throw new ArgumentNullException("enumValue", CoreResources.NullValue);

enumValue = enumValue.Trim();

Type t = typeof(T);

if (!t.IsEnum)
throw new ArgumentException(CoreResources.InvalidType, "enumValue");

return (T)Enum.Parse(t, enumValue, ignoreCase);
}

/// <summary>
///
Parses the enum.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value">
The value.</param>
/// <returns></returns>
[SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter")]
public static T ParseEnum<T>(this string value)
{
if (string.IsNullOrEmpty(value))
throw new ArgumentNullException("value", CoreResources.NullValue);

return ParseEnum<T>(value, false);
}

/// <summary>
///
Parses the enum.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value">
The value.</param>
/// <param name="ignoreCase">
if set to <c>true</c> [ignore case].</param>
/// <returns></returns>
[SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter")]
public static T ParseEnum<T>(this string value, bool ignoreCase)
{
if (string.IsNullOrEmpty(value))
throw new ArgumentNullException("value", CoreResources.NullValue);

return Parse<T>(value, ignoreCase);
}

/// <summary>
///
Gets the enum or default.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value">
The value.</param>
/// <param name="defaultValue">
The default value.</param>
/// <returns></returns>
[SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter")]
[SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes",
Justification = "Never throw the exception in this case")]
public static T GetEnumOrDefault<T>(this string value, T defaultValue)
{
if (string.IsNullOrEmpty(value))
return defaultValue;

try
{
return Parse<T>(value, true);
}
catch
{
return defaultValue;
}
}

/// <summary>
///
Tries to parse the enum. Case insensitive. Returns true/false for errors (or return InvalidArgumentException?)
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value">
The value.</param>
/// <param name="enumInstance">
The enum instance.</param>
/// <returns></returns>
[SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter")]
[SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes",
Justification = "Never throw the exception in this case")]
public static bool TryParseEnum<T>(this string value, out T enumInstance)
{
try
{
enumInstance = Parse<T>(value, true);
return true;
}
catch
{
enumInstance = default(T);
return false;
}
}


/// <summary>
///
Gets the <see cref="DescriptionAttribute" /> of an <see cref="Enum" />
///
type value.
/// </summary>
/// <param name="value">
The <see cref="Enum" /> type value.</param>
/// <returns>
A string containing the text of the
/// <see cref="DescriptionAttribute"/>.</returns>
public static string GetDescription(this Enum value)
{
if (value == null)
throw new ArgumentNullException("value", CoreResources.NullValue);

string description = value.ToString();
FieldInfo fieldInfo = value.GetType().GetField(description);
EnumDescriptionAttribute[] attributes =
(EnumDescriptionAttribute[])
fieldInfo.GetCustomAttributes(typeof(EnumDescriptionAttribute), false);

if (attributes != null && attributes.Length > 0)
{
description = attributes[0].Description;
}
return description;
}

/// <summary>
///
Converts the <see cref="Enum" /> type to an <see cref="IList" />
///
compatible object.
/// </summary>
/// <param name="type">
The <see cref="Enum"/> type.</param>
/// <returns>
An <see cref="IList"/> containing the enumerated
/// type value and description.</returns>
public static IList ToList(this Type type)
{
if (type == null)
throw new ArgumentNullException("type", CoreResources.InvalidType);

ArrayList list = new ArrayList();
Array enumValues = Enum.GetValues(type);

foreach (Enum value in enumValues)
{
list.Add(new KeyValuePair<Enum, string>(value, GetDescription(value)));
}

return list;
}
}