Je voudrais créer une méthode générique pour convertir n'importe quel type dérivé de System.Enum en sa valeur entière correspondante, sans conversion et de préférence sans analyse de chaîne.
Par exemple, ce que je veux, c'est quelque chose comme ceci:
// 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 une expression de type «System.Enum» en type «int».
Maintenant, j'ai trouvé cette solution, mais je préfère avoir quelque chose de plus efficace.
class Converter
{
int ToInteger(System.Enum anEnum)
{
return int.Parse(anEnum.ToString("d"));
}
}
Aucune suggestion?
Réponses:
Si vous ne voulez pas lancer,
pourrait faire l'affaire.
La diffusion directe (via
(int)enumValue
) n'est pas possible. Notez que ce serait aussi « dangereux » car un ENUM peut avoir différents types sous - jacents (int
,long
,byte
...).Plus formellement:
System.Enum
n'a pas de relation d'héritage directe avecInt32
(bien que les deux soientValueType
s), donc le cast explicite ne peut pas être correct dans le système de typesla source
Converter.ToInteger(MyEnum.MyEnumConstant);
ne vous donnera aucune erreur ici. Veuillez modifier cette partie.int
long
enum.System.Enum
est une classe, donc c'est un type de référence. Les valeurs sont probablement encadrées.Je l'ai fait fonctionner en castant sur un objet puis sur un int:
C'est moche et probablement pas la meilleure façon. Je vais continuer à jouer avec, pour voir si je peux trouver quelque chose de mieux ...
EDIT: J'étais sur le point de publier que Convert.ToInt32 (enumValue) fonctionne également, et j'ai remarqué que MartinStettner m'a battu.
Tester:
EDIT 2: Dans les commentaires, quelqu'un a dit que cela ne fonctionne qu'en C # 3.0. Je viens de tester ceci dans VS2005 comme ceci et cela a fonctionné:
la source
Si vous devez convertir une énumération en son type sous-jacent (toutes les énumérations ne sont pas sauvegardées par
int
), vous pouvez utiliser:la source
Convert.ChangeType
accepteobject
pour le premier argument et retourneobject
.Pourquoi avez-vous besoin de réinventer la roue avec une méthode d'aide? Il est parfaitement légal de convertir une
enum
valeur en son type sous-jacent.C'est moins typant, et à mon avis plus lisible, à utiliser ...
... plutôt que quelque chose comme ...
la source
De ma réponse ici :
Donné
e
comme dans:Ensuite, ces travaux:
Les deux derniers sont vraiment laids. Le premier devrait être plus lisible, bien que le second soit beaucoup plus rapide. Ou peut-être qu'une méthode d'extension est la meilleure, le meilleur des deux mondes.
Vous pouvez maintenant appeler:
la source
e
variable a déjà l'instance encadrée de type valeur réelle, c'est-à-dire enum. Lorsque vous écrivez,Enum e = Question.Role;
il est déjà encadré. La question est de reconvertir le boxedSystem.Enum
en type int sous-jacent (unboxing). Donc, ici, le déballage n'est que le problème des performances.(int)(object)e
est un appel de déballage direct; oui devrait être plus rapide que les autres approches. Voir çaCasting from a
System.Enum
to anint
fonctionne très bien pour moi (c'est aussi sur MSDN ). C'est peut-être un bogue Resharper.la source
System.Enum
, pasSystem.Enum
lui-même.Puisque les Enums sont limités à 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, quel conteneur utiliser n'est pas clair car ulong explosera pour les nombres négatifs et long explosera pour les nombres entre long.MaxValue et ulong.MaxValue. Nous devons basculer entre ces choix en fonction du type sous-jacent.
Bien sûr, vous devez toujours 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.
la source
N'oubliez pas que le type Enum lui-même contient un tas de fonctions d'assistance statiques. Si tout ce que vous voulez faire est de convertir une instance de l'énumération en son type entier correspondant, alors la conversion est probablement le moyen le plus efficace.
Je pense que ReSharper se plaint car Enum n'est pas une énumération d'un type particulier, et les énumérations elles-mêmes dérivent d'un type de valeur scalaire, pas Enum. Si vous avez besoin d'un casting adaptable de manière générique, je dirais que cela pourrait bien vous convenir (notez que le type d'énumération lui-même est également inclus dans le générique:
Cela pourrait alors être utilisé comme ceci:
Je ne peux pas le dire avec certitude, mais le code ci-dessus pourrait même être pris en charge par l'inférence de type C #, permettant ce qui suit:
la source
EnumHelpers.Convert<int, StopLight>(StopLight.Red);
place de(int)StopLight.Read;
? Aussi la question parleSystem.Enum
.