在C#中将Int转换为通用枚举
类似于铸造诠释枚举在C#中,但我的枚举是一个genericstypes参数。 处理这个问题的最好方法是什么?
例:
private T ConvertEnum<T>(int i) where T : struct, IConvertible { return (T)i; }
生成编译器错误Cannot convert type 'int' to 'T'
完整代码如下,其中value可以包含int或null。
private int? TryParseInt(string value) { var i = 0; if (!int.TryParse(value, out i)) { return null; } return i; } private T? TryParseEnum<T>(string value) where T : struct, IConvertible { var i = TryParseInt(value); if (!i.HasValue) { return null; } return (T)i.Value; }
我发现的最简单的方法是通过向object
添加一个强制转换来强制编译器的手。
return (T)(object)i.Value;
这是一个非常快速的解决scheme,它滥用了运行时创build静态generics类的多个实例的事实。 释放你的内在优化恶魔!
当你以通用的方式读取stream中的Enums时,这真的很明显。 结合外部类也caching枚举的基础types和一个BitConverter释放真棒。
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); }
在启用了优化的Core i7-3740QM上的结果:
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
你应该可以使用Enum.Parse
来Enum.Parse
这一点:
return (T)Enum.Parse(typeof(T), i.Value.ToString(), true);
本文讨论parsing扩展方法的generics枚举:
- 带扩展方法的genericsparsing
public static class Extensions { public static T ToEnum<T>(this int param) { var info = typeof(T); if (info.IsEnum) { T result = (T)Enum.Parse(typeof(T), param.ToString(), true); return result; } return default(T); } }