580 votes

Obtenir les attributs de la valeur de l'Enum

Je voudrais savoir si il est possible d'obtenir les attributs de l'énumération des valeurs et non de l'enum lui-même? Par exemple, supposons que j'ai l'enum ci-dessous:

enum FunkyAttributesEnum
{
[Description("Name With Spaces1")]
NameWithoutSpaces1,    
[Description("Name With Spaces2")]
NameWithoutSpaces2
}

Ce que je veux, c'est donné le type enum, produire de 2-tuples de enum chaîne de valeur et sa description.

La valeur a été facile:

Array Values = System.Enum.GetValues(typeof(FunkyAttributesEnum));
foreach (int Value in Values)
    Tuple.Value = Enum.GetName(typeof(FunkyAttributesEnum), Value);

Mais comment puis-je obtenir la description la valeur de l'attribut, pour remplir Tuple.Desc? Je ne peux penser à comment le faire si l'Attribut appartient à l'enum lui-même, mais je suis à une perte quant à la façon de l'obtenir à partir de la valeur de l'enum.

545voto

Bryan Rowe Points 3629

Ceci devrait faire ce dont vous avez besoin.

var type = typeof(FunkyAttributesEnum);
var memInfo = type.GetMember(FunkyAttributesEnum.NameWithoutSpaces1.ToString());
var attributes = memInfo[0].GetCustomAttributes(typeof(DescriptionAttribute),
    false);
var description = ((DescriptionAttribute)attributes[0]).Description;

380voto

AdamCrawford Points 960

Ce bout de code devrait vous donner un bon petit méthode d'extension sur toute enum qui vous permet de récupérer un attribut générique. Je crois que c'est différent de la fonction lambda ci-dessus, car il est plus simple à utiliser et légèrement - vous avez seulement besoin de passer dans le type générique.

public static class EnumHelper
{
    /// <summary>
    /// Gets an attribute on an enum field value
    /// </summary>
    /// <typeparam name="T">The type of the attribute you want to retrieve</typeparam>
    /// <param name="enumVal">The enum value</param>
    /// <returns>The attribute of type T that exists on the enum value</returns>
    public static T GetAttributeOfType<T>(this Enum enumVal) where T:System.Attribute
    {
        var type = enumVal.GetType();
        var memInfo = type.GetMember(enumVal.ToString());
        var attributes = memInfo[0].GetCustomAttributes(typeof(T), false);
        return (attributes.Length > 0) ? (T)attributes[0] : null;
    }
}

94voto

Scott Belchak Points 631

C'est un générique de mise en œuvre à l'aide d'un lambda pour la sélection

    public static Expected GetAttributeValue<T, Expected>(this Enum enumeration, Func<T, Expected> expression)
        where T : Attribute
    {
        T attribute =
          enumeration
            .GetType()
            .GetMember(enumeration.ToString())
            .Where(member => member.MemberType == MemberTypes.Field)
            .FirstOrDefault()
            .GetCustomAttributes(typeof(T), false)
            .Cast<T>()
            .SingleOrDefault();

        if (attribute == null)
            return default(Expected);

        return expression(attribute);
    }

L'appeler comme ceci:

string description = targetLevel.GetAttributeValue<DescriptionAttribute, string>(x => x.Description);

86voto

Troy Alford Points 8676

J'ai fusionné un couple de réponses ici pour créer un peu plus extensible solution. Je suis fournissant juste au cas où c'est utile à quelqu'un d'autre dans l'avenir. Message Original ici.

using System;
using System.ComponentModel;

public static class EnumExtensions {

    // This extension method is broken out so you can use a similar pattern with 
    // other MetaData elements in the future. This is your base method for each.
    public static T GetAttribute<T>(this Enum value) where T : Attribute {
        var type = value.GetType();
        var memberInfo = type.GetMember(value.ToString());
        var attributes = memberInfo[0].GetCustomAttributes(typeof(T), false);
        return (T)attributes[0];
    }

    // This method creates a specific call to the above method, requesting the
    // Description MetaData attribute.
    public static string ToName(this Enum value) {
        var attribute = value.GetAttribute<DescriptionAttribute>();
        return attribute == null ? value.ToString() : attribute.Name;
    }

}

Cette solution crée une paire de méthodes d'extension sur le protocole Enum. La première vous permet d'utiliser la réflexion pour récupérer tous les attributs associés à votre valeur. Le second spécifiquement appels récupère l' DisplayAttribute , et le renvoie de l' Name de la valeur.

Considérez, par exemple, à l'aide de l' DisplayAttribute de l'attribut de System.ComponentModel.DataAnnotations

using System.ComponentModel.DataAnnotations;

public enum Days {
    [Display(Name = "Sunday")]
    Sun,
    [Display(Name = "Monday")]
    Mon,
    [Display(Name = "Tuesday")]
    Tue,
    [Display(Name = "Wednesday")]
    Wed,
    [Display(Name = "Thursday")]
    Thu,
    [Display(Name = "Friday")]
    Fri,
    [Display(Name = "Saturday")]
    Sat
}

Pour utiliser l'extension de la méthode, on doit maintenant appeler tout simplement la suivante:

Console.WriteLine(Days.Mon.ToName());

ou

var day = Days.Mon;
Console.WriteLine(day.ToName());

38voto

FunksMaName Points 1362

En plus de @AdamCrawford réponse, j'ai créé des méthodes d'extension d'alimentation pour obtenir la description.

 public static string GetAttributeDescription(this Enum enumValue)
    {
        var attribute = enumValue.GetAttributeOfType<DescriptionAttribute>();

        return attribute == null ? String.Empty : attribute.Description;
    } 

par conséquent, afin d'obtenir la description, vous pouvez soit utiliser l'extension originale de la méthode d'

string desc = myEnumVariable.GetAttributeOfType<DescriptionAttribute>().Description

ou vous pouvez simplement appeler la méthode d'extension ici:

string desc = myEnumVariable.GetAttributeDescription();

Qui devrait, espérons rendre votre code un peu plus lisible.

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