Ecco un soluzione molto veloce che abusa del fatto che il runtime crea più istanze di classi generiche statiche. Scatena i tuoi demoni di ottimizzazione interiore!
Questo brilla davvero quando leggi Enums da un flusso in modo generico. Combina con una classe esterna che memorizza nella cache anche il tipo sottostante all'enumerazione e un BitConverter per scatenare l'impressionante.
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);
}
Risultati sul Core i7-3740QM con ottimizzazioni abilitati:
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
fonte
2014-10-10 00:02:41
http://stackoverflow.com/questions/2745320/enum-tryparse-with-flags-attribute - potrebbero aiutare ? – Sunny
Ultima risposta su http://stackoverflow.com/questions/1331739/enum-type-constraints-in-c-sharp, è più vicino a ciò che desideri. Comunque non è ancora intelligente. Tendo a usare la riflessione per questo, puoi rendere il codice molto più forte. La Struct non è abbastanza restrittiva per fare confusione con i generici, a mio avviso. –
Qualcosa che non box: [c-sharp-non-boxing-conversion-of-generic-enum-to-int] (http://stackoverflow.com/questions/1189144/c-sharp-non-boxing- conversion-of-generic-enum-to-int) – nawfal