347 votes

Enum ToString avec des chaînes de caractères conviviales

Mon enum se compose des valeurs suivantes :

private enum PublishStatusses{
    NotCompleted,
    Completed,
    Error
};

Je veux cependant être en mesure de produire ces valeurs de manière conviviale.
Je n'ai pas besoin de pouvoir repasser de la chaîne à la valeur.

1 votes

Duplicata possible de C# String enums

0 votes

429voto

Ray Booysen Points 10606

J'utilise le Description de l'espace de noms System.ComponentModel. Il suffit de décorer l'enum :

private enum PublishStatusValue
{
    [Description("Not Completed")]
    NotCompleted,
    Completed,
    Error
};

Utilisez ensuite ce code pour le récupérer :

public static string GetDescription<T>(this T enumerationValue)
    where T : struct
{
    Type type = enumerationValue.GetType();
    if (!type.IsEnum)
    {
        throw new ArgumentException("EnumerationValue must be of Enum type", "enumerationValue");
    }

    //Tries to find a DescriptionAttribute for a potential friendly name
    //for the enum
    MemberInfo[] memberInfo = type.GetMember(enumerationValue.ToString());
    if (memberInfo != null && memberInfo.Length > 0)
    {
        object[] attrs = memberInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);

        if (attrs != null && attrs.Length > 0)
        {
            //Pull out the description value
            return ((DescriptionAttribute)attrs[0]).Description;
        }
    }
    //If we have no description attribute, just return the ToString of the enum
    return enumerationValue.ToString();
}

0 votes

Je viens de remarquer que la méthode d'extension actuelle n'utilisait jamais le paramètre de type contraint. je l'ai corrigé pour que le paramètre utilise le type contraint au lieu de l'objet.

16 votes

Cet exemple est plus facile à lire. stackoverflow.com/questions/1415140/

41 votes

Je pense que l'utilisation de la réflexion telle que décrite dans cette solution a un impact significatif sur les performances. Le code de la méthode de Will, qui consiste à utiliser la méthode d'extension ToFriendlyString, est beaucoup plus facile à comprendre, et ses performances devraient également être extrêmement rapides.

412voto

Will Points 76760

Je fais cela avec des méthodes d'extension :

public enum ErrorLevel
{
  None,
  Low,
  High,
  SoylentGreen
}

public static class ErrorLevelExtensions
{
  public static string ToFriendlyString(this ErrorLevel me)
  {
    switch(me)
    {
      case ErrorLevel.None:
        return "Everything is OK";
      case ErrorLevel.Low:
        return "SNAFU, if you know what I mean.";
      case ErrorLevel.High:
        return "Reaching TARFU levels";
      case ErrorLevel.SoylentGreen:
        return "ITS PEOPLE!!!!";
      default:
        return "Get your damn dirty hands off me you FILTHY APE!";
    }
  }
}

0 votes

Oui, merci pour la contribution. J'ai mis quelques remarques dans le post de noldorim concernant cette solution.

9 votes

C'est tellement plus propre que la réponse par attributs. Joli !

3 votes

@pennyrave : Eh. Beaucoup de composants d'interface utilisateur s'attendent à trouver et à utiliser DisplayNameAttribute et DescriptionAttribute. En fait, maintenant, j'utilise ceux-ci et une méthode d'extension pour obtenir facilement ces valeurs.

97voto

annakata Points 42676

Peut-être que je rate quelque chose, mais qu'est-ce qui ne va pas avec Enum.GetName ?

public string GetName(PublishStatusses value)
{
    return Enum.GetName(typeof(PublishStatusses), value)
}

edit : pour des chaînes conviviales, vous devez passer par un .resource pour obtenir l'internationalisation/localisation, et il serait sans doute mieux d'utiliser une clé fixe basée sur la clé de l'enum plutôt qu'un attribut de décorateur sur la même.

13 votes

Je renvoie la valeur littérale de l'énumération, pas une valeur conviviale.

2 votes

Oic - il y a de fortes chances que vous deviez passer par une bibliothèque de ressources de chaînes de caractères basée sur cette valeur, car l'alternative (attributs de décorateurs) ne supportera pas I18N.

1 votes

Dans le cas de l'I18N, la méthode GetDescription() rechercherait dans la bibliothèque des ressources une chaîne traduite et se replierait sur la description, puis sur le littéral.

20voto

Noldorin Points 67794

La solution la plus simple consiste à utiliser une méthode d'extension personnalisée (dans .NET 3.5 au moins - vous pouvez simplement la convertir en une méthode d'aide statique pour les versions antérieures du framework).

public static string ToCustomString(this PublishStatusses value)
{
    switch(value)
    {
        // Return string depending on value.
    }
    return null;
}

Je suppose ici que vous voulez retourner autre chose que le nom réel de la valeur de l'enum (que vous pouvez obtenir en appelant simplement ToString).

0 votes

Bien que valable, je préfère la méthode des attributs. De cette façon, je peux mettre ma méthode toSTring dans une bibliothèque séparée, tout en mettant la représentation de la chaîne personnalisée avec l'enum elle-même.

1 votes

C'est vrai. Je suppose qu'un avantage de cette méthode est que vous pouvez inclure un argument avec la méthode spécifiant une certaine variable d'état, et ensuite changer la représentation de la chaîne de caractères qui est retournée en fonction de cela.

1 votes

Oui, tout dépend de la portée de la méthode, je suppose. Alors que la méthode des attributs est plus générique, votre solution est plus localisée C'est une question de besoins en fin de compte.

13voto

Lemmy Points 1452

L'autre article concerne Java. Vous ne pouvez pas mettre de méthodes dans les Enums en C#.

fais juste quelque chose comme ça :

PublishStatusses status = ...
String s = status.ToString();

Si vous souhaitez utiliser des valeurs d'affichage différentes pour vos valeurs d'enum, vous pouvez utiliser les attributs et Reflection.

3 votes

ToString n'est pas sûr dans tous les cas - une énumération avec plusieurs entrées avec la même valeur (par exemple pour les énumérations d'entiers) retournera la clé de la première valeur correspondante, pas la clé de l'élément testé, c'est pourquoi Enum.GetName est préféré.

4 votes

C'était la solution la plus simple pour son enum spécifique.

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