Cast Int to Generic Enum in C#
The simplest way I have found is to force the compiler's hand by adding a cast to object
.
return (T)(object)i.Value;
You should be able to use Enum.Parse
for this:
return (T)Enum.Parse(typeof(T), i.Value.ToString(), true);
This article talks about parsing generic enums for extenstion methods:
- Generic Enum Parsing with Extension Methods
Here's a very fast solution that abuses the fact that the runtime creates multiple instances of static generic classes. Unleash your inner optimization demons!
This really shines when you're reading Enums from a stream in a generic fashion. Combine with an outer class that also caches the enum's underlying type and a BitConverter to unleash the awesome.
void Main()
{
Console.WriteLine("Cast (reference): {0}", (TestEnum)5);
Console.WriteLine("EnumConverter: {0}", EnumConverter<TestEnum>.Convert(5));
Console.WriteLine("Enum.ToObject: {0}", Enum.ToObject(typeof(TestEnum), 5));
int iterations = 1000 * 1000 * 100;
Measure(iterations, "Cast (reference)", () => { var t = (TestEnum)5; });
Measure(iterations, "EnumConverter", () => EnumConverter<TestEnum>.Convert(5));
Measure(iterations, "Enum.ToObject", () => Enum.ToObject(typeof(TestEnum), 5));
}
static class EnumConverter<TEnum> where TEnum : struct, IConvertible
{
public static readonly Func<long, TEnum> Convert = GenerateConverter();
static Func<long, TEnum> GenerateConverter()
{
var parameter = Expression.Parameter(typeof(long));
var dynamicMethod = Expression.Lambda<Func<long, TEnum>>(
Expression.Convert(parameter, typeof(TEnum)),
parameter);
return dynamicMethod.Compile();
}
}
enum TestEnum
{
Value = 5
}
static void Measure(int repetitions, string what, Action action)
{
action();
var total = Stopwatch.StartNew();
for (int i = 0; i < repetitions; i++)
{
action();
}
Console.WriteLine("{0}: {1}", what, total.Elapsed);
}
Results on Core i7-3740QM with optimizations enabled:
Cast (reference): Value
EnumConverter: Value
Enum.ToObject: Value
Cast (reference): 00:00:00.3175615
EnumConverter: 00:00:00.4335949
Enum.ToObject: 00:00:14.3396366