Intégrer à Enum générique en C #

Similaire à Cast int pour enum en C # mais mon enum est un paramètre de type générique. Quelle est la meilleure façon de gérer cela?

Exemple:

private T ConvertEnum(int i) where T : struct, IConvertible { return (T)i; } 

Génère une erreur de compilation Cannot convert type 'int' to 'T'

Le code complet est le suivant, où value peut contenir l’int ou null.

 private int? TryParseInt(ssortingng value) { var i = 0; if (!int.TryParse(value, out i)) { return null; } return i; } private T? TryParseEnum(ssortingng value) where T : struct, IConvertible { var i = TryParseInt(value); if (!i.HasValue) { return null; } return (T)i.Value; } 

La manière la plus simple que j’ai trouvée est de forcer la main du compilateur en ajoutant une dissortingbution à l’ object .

 return (T)(object)i.Value; 

Vous devriez pouvoir utiliser Enum.Parse pour cela:

 return (T)Enum.Parse(typeof(T), i.Value.ToSsortingng(), true); 

Cet article parle de l’parsing syntaxique des énumérations génériques pour les méthodes d’extension:

  • Analyse Enum générique avec des méthodes d’extension

Voici une solution très rapide qui abuse du fait que le runtime crée plusieurs instances de classes génériques statiques. Libérez vos démons d’optimisation intérieure!

Cela brille vraiment lorsque vous lisez Enums d’un stream de manière générique. Combinez-le avec une classe externe qui met également en cache le type sous-jacent de l’enum et un BitConverter pour libérer le génial.

 void Main() { Console.WriteLine("Cast (reference): {0}", (TestEnum)5); Console.WriteLine("EnumConverter: {0}", EnumConverter.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.Convert(5)); Measure(iterations, "Enum.ToObject", () => Enum.ToObject(typeof(TestEnum), 5)); } static class EnumConverter where TEnum : struct, IConvertible { public static readonly Func Convert = GenerateConverter(); static Func GenerateConverter() { var parameter = Expression.Parameter(typeof(long)); var dynamicMethod = Expression.Lambda>( Expression.Convert(parameter, typeof(TEnum)), parameter); return dynamicMethod.Comstack(); } } enum TestEnum { Value = 5 } static void Measure(int repetitions, ssortingng what, Action action) { action(); var total = Stopwatch.StartNew(); for (int i = 0; i < repetitions; i++) { action(); } Console.WriteLine("{0}: {1}", what, total.Elapsed); } 

Résultats sur Core i7-3740QM avec optimisations activées:

 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 

Sinon, si vous pouvez obtenir un enum non pas comme un type générique, mais comme Type, utilisez simplement

 Enum.ToObject 

https://msdn.microsoft.com/en-us/library/system.enum.toobject(v=vs.110).aspx

 public static class Extensions { public static T ToEnum(this int param) { var info = typeof(T); if (info.IsEnum) { T result = (T)Enum.Parse(typeof(T), param.ToSsortingng(), true); return result; } return default(T); } }