56 votes

Comment obtenir des valeurs d'attribut personnalisé pour les énumérations ?

J'ai une énumération où chaque membre a un attribut personnalisé qui lui est appliqué. Comment puis-je récupérer la valeur stockée dans chaque attribut ?

En ce moment je fais ça :

 var attributes = typeof ( EffectType ).GetCustomAttributes ( false );
foreach ( object attribute in attributes )
{
    GPUShaderAttribute attr = ( GPUShaderAttribute ) attribute;
    if ( attr != null )
        return attr.GPUShader;
}
return 0;

Un autre problème est, s'il n'est pas trouvé, que dois-je retourner ? 0 est l'implicité convertible en n'importe quelle énumération, n'est-ce pas ? C'est pourquoi je l'ai retourné.

J'ai oublié de mentionner que le code ci-dessus renvoie 0 pour chaque membre enum.

78voto

George Kargakis Points 968

Essayez d'utiliser une méthode générique

Attribut:

 class DayAttribute : Attribute
{
    public string Name { get; private set; }

    public DayAttribute(string name)
    {
        this.Name = name;
    }
}

Énumération :

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

Méthode générique :

         public static TAttribute GetAttribute<TAttribute>(this Enum value)
        where TAttribute : Attribute
    {
        var enumType = value.GetType();
        var name = Enum.GetName(enumType, value);
        return enumType.GetField(name).GetCustomAttributes(false).OfType<TAttribute>().SingleOrDefault();
    }

Invoquer:

         static void Main(string[] args)
    {
        var day = Days.Mon;
        Console.WriteLine(day.GetAttribute<DayAttribute>().Name);
        Console.ReadLine();
    }

Résultat:

Lundi

26voto

user1779271 Points 269

Il existe une autre méthode pour le faire avec les génériques :

 public static T GetAttribute<T>(Enum enumValue) where T: Attribute
{
    T attribute;

    MemberInfo memberInfo = enumValue.GetType().GetMember(enumValue.ToString())
                                    .FirstOrDefault();

    if (memberInfo != null)
    {
        attribute = (T) memberInfo.GetCustomAttributes(typeof (T), false).FirstOrDefault();
        return attribute;
    }
    return null;
}

2voto

Michelle Lam Points 53

En supposant que GPUShaderAttribute :

 [AttributeUsage(AttributeTargets.Field,AllowMultiple =false)]
public class GPUShaderAttribute: Attribute
{
    public GPUShaderAttribute(string value)
    {
        Value = value;
    }
    public string Value { get; internal set; }
}

Ensuite, nous pourrions écrire quelques méthodes génériques pour renvoyer un dictionnaire des valeurs enum et de l'objet GPUShaderAttribute .

     /// <summary>
    /// returns the attribute for a given enum
    /// </summary>        
    public static TAttribute GetAttribute<TAttribute>(IConvertible @enum)
    {
        TAttribute attributeValue = default(TAttribute);
        if (@enum != null)
        {
            FieldInfo fi = @enum.GetType().GetField(@enum.ToString());
            attributeValue = fi == null ? attributeValue : (TAttribute)fi.GetCustomAttributes(typeof(TAttribute), false).DefaultIfEmpty(null).FirstOrDefault();

        }
        return attributeValue;
    }

Renvoyez ensuite l'ensemble avec cette méthode.

 /// <summary>
/// Returns a dictionary of all the Enum fields with the attribute.
/// </summary>
public static Dictionary<Enum, RAttribute> GetEnumObjReference<TEnum, RAttribute>()
{
    Dictionary<Enum, RAttribute> _dict = new Dictionary<Enum, RAttribute>();
    Type enumType = typeof(TEnum);
    Type enumUnderlyingType = Enum.GetUnderlyingType(enumType);
    Array enumValues = Enum.GetValues(enumType);
    foreach (Enum enumValue in enumValues)
    {
        _dict.Add(enumValue, GetAttribute<RAttribute>(enumValue));
    }

    return _dict;
}

Si vous vouliez juste une valeur de chaîne, je recommanderais un itinéraire légèrement différent.

     /// <summary>
    /// Returns the string value of the custom attribute property requested.
    /// </summary>
    public static string GetAttributeValue<TAttribute>(IConvertible @enum, string propertyName = "Value")
    {
        TAttribute attribute = GetAttribute<TAttribute>(@enum);
        return attribute == null ? null : attribute.GetType().GetProperty(propertyName).GetValue(attribute).ToString();

    }

    /// <summary>
    /// Returns a dictionary of all the Enum fields with the string of the property from the custom attribute nulls default to the enumName
    /// </summary>
    public static Dictionary<Enum, string> GetEnumStringReference<TEnum, RAttribute>(string propertyName = "Value")
    {
        Dictionary<Enum, string> _dict = new Dictionary<Enum, string>();
        Type enumType = typeof(TEnum);
        Type enumUnderlyingType = Enum.GetUnderlyingType(enumType);
        Array enumValues = Enum.GetValues(enumType);
        foreach (Enum enumValue in enumValues)
        {
            string enumName = Enum.GetName(typeof(TEnum), enumValue);
            string decoratorValue = Common.GetAttributeValue<RAttribute>(enumValue, propertyName) ?? enumName;
            _dict.Add(enumValue, decoratorValue);
        }

        return _dict;
    }

1voto

Veverke Points 2940
public string GetEnumAttributeValue(Enum enumValue, Type attributeType, string attributePropertyName)
        {
            /* New generic version (GetEnumDescriptionAttribute results can be achieved using this new GetEnumAttribute with a call like (enumValue, typeof(DescriptionAttribute), "Description")
             * Extracts a given attribute value from an enum:
             *
             * Ex:
             * public enum X
             * {
                     [MyAttribute(myProp = "aaaa")]
             *       x1,
             *       x2,
             *       [Description("desc")]
             *       x3
             * }
             *
             * Usage:
             *      GetEnumAttribute(X.x1, typeof(MyAttribute), "myProp") returns "aaaa"
             *      GetEnumAttribute(X.x2, typeof(MyAttribute), "myProp") returns string.Empty
             *      GetEnumAttribute(X.x3, typeof(DescriptionAttribute), "Description") returns "desc"
             */

            var attributeObj = enumValue.GetType()?.GetMember(enumValue.ToString())?.FirstOrDefault()?.GetCustomAttributes(attributeType, false)?.FirstOrDefault();

            if (attributeObj == null)
                return string.Empty;
            else
            {
                try
                {
                    var attributeCastedObj = Convert.ChangeType(attributeObj, attributeType);
                    var attributePropertyValue = attributeType.GetProperty(attributePropertyName)?.GetValue(attributeCastedObj);
                    return attributePropertyValue?.ToString() ?? string.Empty;
                }
                catch (Exception ex)
                {
                    return string.Empty;
                }
            }
        }

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