EnumEx.cs
using System;
using System.Collections.Generic;
using System.Reflection;
class Program
{
static void Main(string[] args)
{
object vt1;
bool b1 = EnumEx.TryParse(typeof(FizzBuzz), "Buzz", out vt1);
Console.WriteLine("{0} {1}", b1, vt1);
object vt2;
bool b2 = EnumEx.TryParse(typeof(FizzBuzz), "-", out vt2);
Console.WriteLine("{0} {1}", b2, vt2);
}
}
enum FizzBuzz
{
Fizz,
Buzz
}
class EnumEx
{
private delegate Tuple<bool, object> Parser(string value);
private static readonly MethodInfo genericMethod = typeof(EnumEx).GetMethod("DoTryParse", BindingFlags.NonPublic | BindingFlags.Static);
private static readonly Dictionary<Type, Parser> delegates = new Dictionary<Type, Parser>();
public static bool TryParse(Type enumType, string value, out object result)
{
if (enumType == null)
{
throw new ArgumentNullException("enumType");
}
if (!enumType.IsEnum)
{
throw new ArgumentException("enumType is not Enum");
}
if (value == null)
{
result = (ValueType)Activator.CreateInstance(enumType);
return false;
}
Parser p;
if (!delegates.TryGetValue(enumType, out p))
{
p = (Parser)Delegate.CreateDelegate(typeof(Parser), genericMethod.MakeGenericMethod(enumType));
delegates[enumType] = p;
}
var tuple = p.Invoke(value);
result = tuple.Item2;
return tuple.Item1;
}
private static Tuple<bool, object> DoTryParse<TEnum>(string value)
where TEnum : struct
{
TEnum e;
bool success = Enum.TryParse<TEnum>(value, out e);
return Tuple.Create(success, (object)e);
}
}