web-dev-qa-db-fra.com

Comment obtenir la description C # Enum de la valeur?

Duplicate possible:
Obtenir les attributs de la valeur d’Enum

J'ai un enum avec des attributs Description comme ceci:

public enum MyEnum
{
    Name1 = 1,
    [Description("Here is another")]
    HereIsAnother = 2,
    [Description("Last one")]
    LastOne = 3
}

J'ai trouvé ce morceau de code pour récupérer la description basée sur un Enum

public static string GetEnumDescription(Enum value)
{
    FieldInfo fi = value.GetType().GetField(value.ToString());

    DescriptionAttribute[] attributes = fi.GetCustomAttributes(typeof(DescriptionAttribute), false) as DescriptionAttribute[];

    if (attributes != null && attributes.Any())
    {
        return attributes.First().Description;
    }

    return value.ToString();
}

Cela me permet d’écrire du code comme:

var myEnumDescriptions = from MyEnum n in Enum.GetValues(typeof(MyEnum))
                         select new { ID = (int)n, Name = Enumerations.GetEnumDescription(n) };

Ce que je veux faire, c'est si je connais la valeur enum (par exemple 1) - comment puis-je récupérer la description? En d'autres termes, comment puis-je convertir un entier en une "valeur Enum" à transmettre à ma méthode GetDescription?

351
davekaro
int value = 1;
string description = Enumerations.GetEnumDescription((MyEnum)value);

Le type de données sous-jacent par défaut pour un enum en C # est un int, vous pouvez simplement le transtyper.

335
Nicholas Piasecki

Mise à jour

La bibliothèque Mélodie sans contrainte n'est plus maintenue; Le support a été abandonné en faveur de Enums.NET .

Dans Enums.NET, vous utiliseriez:

string description = ((MyEnum)value).AsString(EnumFormat.Description);

Original post

J'ai implémenté cela d'une manière générique et sans risque pour le type dans Mélodie sans contrainte - vous utiliseriez:

string description = Enums.GetDescription((MyEnum)value);

Cette:

  • Assure (avec des contraintes de type génériques) que la valeur est vraiment une valeur enum
  • Evite la boxe dans votre solution actuelle
  • Met en cache toutes les descriptions pour éviter d'utiliser la réflexion sur chaque appel
  • A un tas d'autres méthodes, y compris la possibilité d'analyser la valeur de la description

Je me rends compte que la réponse fondamentale était simplement le casting d'un int à MyEnum, mais si vous faites beaucoup de travail enum, cela vaut la peine de penser à utiliser Unconstrained Melody :)

85
Jon Skeet

Je rassemble le code de la réponse acceptée dans une méthode d'extension générique, afin qu'il puisse être utilisé pour tous types d'objets:

public static string DescriptionAttr<T>(this T source)
{
    FieldInfo fi = source.GetType().GetField(source.ToString());

    DescriptionAttribute[] attributes = (DescriptionAttribute[])fi.GetCustomAttributes(
        typeof(DescriptionAttribute), false);

    if (attributes != null && attributes.Length > 0) return attributes[0].Description;
    else return source.ToString();
}

En utilisant une énumération comme dans le message d'origine, ou toute autre classe dont la propriété est décorée avec l'attribut Description, le code peut être utilisé de la manière suivante:

string enumDesc = MyEnum.HereIsAnother.DescriptionAttr();
string classDesc = myInstance.SomeProperty.DescriptionAttr();
73
Irish

Pour rendre cela plus facile à utiliser, j'ai écrit une extension générique:

public static string ToDescription<TEnum>(this TEnum EnumValue) where TEnum : struct
{
    return Enumerations.GetEnumDescription((Enum)(object)((TEnum)EnumValue));
}

maintenant je peux écrire:

        MyEnum my = MyEnum.HereIsAnother;
        string description = my.ToDescription();
        System.Diagnostics.Debug.Print(description);

Remarque: remplacez "Énumérations" ci-dessus par votre nom de classe.

29
David

Vous ne pouvez pas facilement le faire de manière générique: vous ne pouvez convertir qu'un entier en un type spécifique d'énum. Comme l'a montré Nicholas, il s'agit d'un casting trivial si vous ne vous souciez que d'un seul type d'énum, ​​mais si vous souhaitez écrire une méthode générique pouvant gérer différents types d'énums, les choses deviennent un peu plus compliquées. Vous voulez une méthode dans le sens de:

public static string GetEnumDescription<TEnum>(int value)
{
  return GetEnumDescription((Enum)((TEnum)value));  // error!
}

mais cela entraîne une erreur du compilateur: "int ne peut pas être converti en TEnum" (et si vous contournez ceci, ce "TEnum ne peut pas être converti en Enum"). Vous devez donc tromper le compilateur en insérant des transtypages dans un objet:

public static string GetEnumDescription<TEnum>(int value)
{
  return GetEnumDescription((Enum)(object)((TEnum)(object)value));  // ugly, but works
}

Vous pouvez maintenant appeler cela pour obtenir une description du type d’énum en question:

GetEnumDescription<MyEnum>(1);
GetEnumDescription<YourEnum>(2);
7
itowlson