214 votes

Convertir un Enum en String

Quelle est la meilleure façon de convertir un Enum en String dans .NET 3.5 ?

  • Enum.GetName
  • Enum.Format
  • ToString

Pourquoi devrais-je préférer l'un de ces produits aux autres ? L'un d'eux est-il plus performant ?

13 votes

J'ai cherché et je n'ai pas pu trouver de doublon. Si vous pouvez fournir un lien, je supprimerai cette question.

1 votes

Parfois, l'utilisation d'une instruction switch n'est pas la meilleure pratique (lorsque vous avez de grandes énumérations), vous pouvez utiliser Dict<> à la place.

1 votes

Si vous voulez de meilleures performances, vous pouvez utiliser la classe décrite dans cet article. codeproject.com/KB/dotnet/enum.aspx . L'utilisation ressemblera à ceci Enum<VotreEnum>.ToString(votreValeur) ou Enum<VotreEnum>.ToString((int)votreValeur)

199voto

Keith Points 46288

Depuis C#6, le meilleur moyen d'obtenir le nom d'un enum est la nouvelle fonction nameof opérateur :

nameof(MyEnum.EnumValue);

// Ouputs
> "EnumValue"

Cela fonctionne au moment de la compilation, l'enum étant remplacé par la chaîne de caractères dans le résultat compilé, ce qui signifie que c'est la méthode la plus rapide possible.

Toute utilisation des noms d'enum interfère avec l'obscurcissement du code, si vous considérez que l'obscurcissement des noms d'enum est utile ou important - c'est probablement une toute autre question.

103voto

Sumtraveller Points 553

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);
}

8 votes

Enum.GetName prend la valeur comme argument d'objet. Cela signifie que la valeur sera mise en boîte, ce qui entraînera un gaspillage de ressources CPU lors de l'allocation et du ramassage des déchets. Si cela est fait souvent, Enum.GetName aura un débit beaucoup plus faible que de mettre en cache les valeurs dans un dictionnaire et d'y chercher le nom.

1 votes

@Ran alors quelle est la solution, laquelle utiliser à la place ?

1 votes

Rend mon projet plus lent. toString() est plus rapide.

40voto

Andrei Mikhalevich Points 6372

Enum.GetName(...)

C'est la méthode la plus élégante qui lui est destinée.

var enumValueString = Enum.GetName(typeof (MyEnum), MyEnum.MyValue);

Bien que je ne voie aucun problème à appeler .ToString() car il est tout simplement plus court.

var enumValueString = MyEnum.MyValue.ToString();

Avec la nouvelle syntaxe C# 6, vous pouvez utiliser :

nameof(MyEnum.MyValue)

37voto

nawfal Points 13500

Dans mes tests, Enum.GetName était plus rapide et avec une bonne marge. En interne ToString appelle Enum.GetName . 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 avec certitude que c'est la raison, mais les tests montrent que l'un est plus rapide que l'autre. Les deux appels impliquent une mise en boîte (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.

Configuration du test : enum avec 8 valeurs, nombre d'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()

25voto

David Morton Points 10519

Toutes ces méthodes internes finissent par appeler une méthode appelée InternalGetValueAsString . La différence entre ToString y GetName serait que GetName doit d'abord vérifier certaines choses :

  1. Le type que vous avez entré n'est pas nul.
  2. Le type que vous avez saisi est, en fait, une énumération.
  3. La valeur que vous avez passée n'est pas nulle.
  4. La valeur que vous avez transmise est d'un type qu'une énumération peut effectivement utiliser comme type sous-jacent, ou du type de l'énumération elle-même. Il utilise GetType sur la valeur pour le vérifier.

.ToString n'a pas à s'inquiéter de ces problèmes, car elle est appelée sur une instance de la classe elle-même, et non sur une version passée, donc, en raison du fait que l'option .ToString ne présente pas les mêmes problèmes de vérification que les méthodes statiques, j'en conclurais que la méthode .ToString est le moyen le plus rapide d'obtenir la valeur sous forme de chaîne.

4 votes

Où les avez-vous trouvés ? Quelle était la version de montage ? J'obtiens des résultats très différents.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X