J'aimerais créer une méthode générique pour convertir tout type dérivé System.Enum en sa valeur entière correspondante, sans transtypage et de préférence sans analyser une chaîne.
Par exemple, ce que je veux, c'est quelque chose comme ça:
// Trivial example, not actually what I'm doing.
class Converter
{
int ToInteger(System.Enum anEnum)
{
(int)anEnum;
}
}
Mais cela ne semble pas fonctionner. Resharper signale que vous ne pouvez pas convertir l'expression de type 'System.Enum' en 'int'.
Maintenant, je propose cette solution mais je préférerais quelque chose de plus efficace.
class Converter
{
int ToInteger(System.Enum anEnum)
{
return int.Parse(anEnum.ToString("d"));
}
}
Aucune suggestion?
Si vous ne voulez pas lancer,
Convert.ToInt32()
pourrait faire l'affaire.
La diffusion directe (via (int)enumValue
) n'est pas possible. Notez que cela serait également "dangereux" car une énumération peut avoir différents types sous-jacents (int
, long
, byte
...).
Plus formellement: System.Enum
n'a pas de relation d'héritage directe avec Int32
(bien que les deux soient ValueType
s), la conversion explicite ne peut donc pas être correcte dans le système de types
Je l’ai obtenu en travaillant sur un objet, puis sur un int:
public static class EnumExtensions
{
public static int ToInt(this Enum enumValue)
{
return (int)((object)enumValue);
}
}
C'est moche et probablement pas le meilleur moyen. Je vais continuer à jouer avec pour voir si je peux trouver quelque chose de mieux ...
EDIT: Était sur le point de publier que Convert.ToInt32 (enumValue) fonctionne également, et a remarqué que MartinStettner me battait.
public static class EnumExtensions
{
public static int ToInt(this Enum enumValue)
{
return Convert.ToInt32(enumValue);
}
}
Tester:
int x = DayOfWeek.Friday.ToInt();
Console.WriteLine(x); // results in 5 which is int value of Friday
EDIT 2: Dans les commentaires, quelqu'un a dit que cela ne fonctionne qu'en C # 3.0. Je viens de tester cela dans VS2005 comme ça et cela a fonctionné:
public static class Helpers
{
public static int ToInt(Enum enumValue)
{
return Convert.ToInt32(enumValue);
}
}
static void Main(string[] args)
{
Console.WriteLine(Helpers.ToInt(DayOfWeek.Friday));
}
Si vous devez convertir any enum en son type sous-jacent (toutes les énumérations ne sont pas sauvegardées par int
), vous pouvez utiliser:
return System.Convert.ChangeType(
enumValue,
Enum.GetUnderlyingType(enumValue.GetType()));
Pourquoi avez-vous besoin de réinventer la roue avec une méthode d'assistance? Il est parfaitement légal de convertir une valeur enum
en son type sous-jacent.
C'est moins taper, et à mon avis plus lisible, à utiliser ...
int x = (int)DayOfWeek.Tuesday;
... plutôt que quelque chose comme ...
int y = Converter.ToInteger(DayOfWeek.Tuesday);
// or
int z = DayOfWeek.Tuesday.ToInteger();
De ma réponse ici :
e
comme dans:
Enum e = Question.Role;
Ensuite, ces travaux:
int i = Convert.ToInt32(e);
int i = (int)(object)e;
int i = (int)Enum.Parse(e.GetType(), e.ToString());
int i = (int)Enum.ToObject(e.GetType(), e);
Les deux derniers sont tout simplement laids. Le premier devrait être plus lisible, bien que le second soit beaucoup plus rapide. Ou peut-être une méthode d'extension est le meilleur, le meilleur des deux mondes.
public static int GetIntValue(this Enum e)
{
return e.GetValue<int>();
}
public static T GetValue<T>(this Enum e) where T : struct, IComparable, IFormattable, IConvertible, IComparable<T>, IEquatable<T>
{
return (T)(object)e;
}
Maintenant, vous pouvez appeler:
e.GetValue<int>(); //or
e.GetIntValue();
Transtyper un System.Enum
dans une int
me convient très bien (il s’agit également du MSDN ). C'est peut-être un bogue Resharper.
Puisque les énumérations sont limitées à byte, sbyte, short, ushort, int, uint, long et ulong, nous pouvons faire certaines hypothèses.
Nous pouvons éviter les exceptions lors de la conversion en utilisant le plus grand conteneur disponible. Malheureusement, le conteneur à utiliser n'est pas clair car ulong explose pour les nombres négatifs et long pour les nombres compris entre long.MaxValue et ulong.MaxValue. Nous devons basculer entre ces choix en fonction du type sous-jacent.
Bien sûr, vous devez encore décider quoi faire lorsque le résultat ne rentre pas dans un int. Je pense que le casting est correct, mais il y a encore des pièges:
Voici ma suggestion, je laisserai au lecteur le soin de décider où exposer cette fonction; comme aide ou extension.
public int ToInt(Enum e)
{
unchecked
{
if (e.GetTypeCode() == TypeCode.UInt64)
return (int)Convert.ToUInt64(e);
else
return (int)Convert.ToInt64(e);
}
}