Convertir Enum en chaîne
Quel est le moyen préféré pour convertir une énumération en une chaîne dans. net 3.5?
- Enum.GetName
- Enum.Format
- toString
Pourquoi devrais-je préférer l'un d'eux aux autres? N'est-on effectuer mieux?
12 réponses
De C#6 le meilleur moyen d'obtenir le nom d'un enum est le nouveau nameof
opérateur:
nameof(MyEnum.EnumValue);
// Ouputs
> "EnumValue"
Cela fonctionne au moment de la compilation, l'énumération étant remplacée par la chaîne dans le résultat compilé, ce qui signifie que c'est le moyen le plus rapide possible.
Toute utilisation de noms enum interfère avec l'obscurcissement du code, si vous considérez l'obscurcissement des noms enum comme intéressant ou important - c'est probablement une toute autre question.
Fonctionne pour notre projet...
public static String convertToString(this Enum eff)
{
return Enum.GetName(eff.GetType(), eff);
}
public static EnumType converToEnum<EnumType>(this String enumValue)
{
return (EnumType) Enum.Parse(typeof(EnumType), enumValue);
}
Tous ces éléments finissent par appeler une méthode appelée InternalGetValueAsString
. La différence entre ToString
et GetName
serait que GetName
a pour vérifier quelques choses d'abord:
- le type que vous avez entré n'est pas null.
- Le type que vous avez entré est en fait une énumération.
- la valeur que vous avez transmise n'est pas null.
- la valeur que vous avez transmise est d'un type qu'une énumération peut réellement utiliser en tant que type sous-jacent, ou du type de l'énumération elle-même. Il utilise
GetType
sur la valeur pour vérifier cela.
.ToString
n'a pas à s'inquiéter de l'un de ces problèmes ci-dessus, car il est appelé sur une instance de la classe elle-même, et non sur une version passée, donc, en raison du fait que la méthode .ToString
n'a pas les mêmes problèmes de vérification que les méthodes statiques, Je conclurais que .ToString
est le moyen le plus rapide
Dans mes tests, Enum.GetName
était plus rapide et par marge décente. En interne ToString
appelle Enum.GetName
. à partir de la source pour. NET 4.0, l'essentiel:
public override String ToString()
{
return Enum.InternalFormat((RuntimeType)GetType(), GetValue());
}
private static String InternalFormat(RuntimeType eT, Object value)
{
if (!eT.IsDefined(typeof(System.FlagsAttribute), false))
{
String retval = GetName(eT, value); //<== the one
if (retval == null)
return value.ToString();
else
return retval;
}
else
{
return InternalFlagsFormat(eT, value);
}
}
Je ne peux pas dire que c'est la raison à coup sûr, mais les tests indiquent que l'un est plus rapide que l'autre. Les deux appels impliquent la boxe (en fait, ce sont des appels de réflexion, vous récupérez essentiellement des noms de champs) et peuvent être lents à votre goût.
La configuration de Test: enum avec 8 valeurs, pas de. des itérations = 1000000
Résultat: Enum.GetName = > 700 ms, ToString = > 2000 ms
Si la vitesse n'est pas perceptible, Je ne m'en soucierais pas et utiliserais ToString
car il offre un appel beaucoup plus propre. Contraste
Enum.GetName(typeof(Bla), value)
Avec
value.ToString()
Le mieux que je puisse trouver est cette question non liée sur MSDN , qui contient un extrait XML qui répond à cette question. Toutes ces méthodes partagent le même défaut: elles appellent enum.toString()
, ce qui ne fonctionne pas correctement lors de l'utilisation de Dotfuscation. D'autres préoccupations semblent se rapporter à la boxe indirecte (GetName et Format). Malheureusement, je ne trouve aucune raison de performance pour utiliser l'un des éléments ci-dessus.
Paraphraser à partir de l'extrait xml ,
Passer une boîte enum à chaîne.Format () ou toute autre fonction peut entraîner l'appel de
enum.ToString()
. Cela causera des problèmes lors de Dotfuscating. Vous ne devriez pas utiliserenum.ToString()
,enum.GetNames()
,enum.GetName()
,enum.Format()
ouenum.Parse()
pour convertir une énumération en chaîne. Au lieu de cela, utilisez une instruction switch, et internationalisez également les noms si nécessaire.
Enum.GetName()
Format()
est vraiment juste un wrapper autour de GetName()
avec une fonctionnalité de formatage (ou InternalGetValueAsString()
pour être exact). ToString()
est à peu près le même que Format()
. Je pense que GetName()
est la meilleure option car il est tout à fait évident ce qu'il fait pour quiconque lit la source.
Enum.GetName(...)
C'est la méthode la plus élégante qui est faite pour elle.
var enumValueString = Enum.GetName(typeof (MyEnum), MyEnum.MyValue);
Bien que je ne vois aucun problème avec l'appel .ToString()
car il est simplement plus court.
var enumValueString = MyEnum.MyValue.ToString();
Avec la nouvelle syntaxe C # 6, Vous pouvez utiliser:
nameof(MyEnum.MyValue)
Je crée une méthode d'extension "Description" et l'attache à l'énumération afin que je puisse obtenir un nommage vraiment convivial qui inclut des espaces et des boîtiers. Je n'ai jamais aimé utiliser la valeur enum elle-même comme texte affichable car c'est quelque chose que les développeurs utilisent pour créer du code plus lisible. Il n'est pas destiné à l'affichage de L'interface utilisateur. Je veux être en mesure de changer l'interface utilisateur sans passer par et changer enums partout.
Je ne sais pas quelle est la méthode" préférée " (demandez à 100 personnes et obtenez 100 opinions différentes) mais faites ce qui est le plus simple et ce qui fonctionne. GetName
fonctionne mais nécessite beaucoup plus de frappes. ToString()
semble faire le travail très bien.
Cela fonctionnerait aussi.
List<string> names = Enum.GetNames(typeof(MyEnum)).ToList();
Pour les aficionados de VB:
EnumStringValue = System.Enum.GetName(GetType(MyEnum), MyEnumValue)
Simple: énumérer les noms dans une liste:
List<String> NameList = Enum.GetNames(typeof(YourEnumName)).Cast<string>().ToList()