我想知道是否有可能获得枚举值的属性,而不是枚举本身?例如,假设我有以下枚举:

using System.ComponentModel; // for DescriptionAttribute

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

我想要的是给定枚举类型,产生枚举字符串值及其描述的二元组。

价值很简单:

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

但我如何获得描述属性的值,以填充Tuple.Desc?如果属性属于枚举本身,我可以想到如何做到这一点,但我不知道如何从枚举的值中获得它。


当前回答

下面是AdamCrawford的答案的。net核心版本,使用System.Reflection.TypeExtensions;

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>
    /// <example>string desc = myEnumVariable.GetAttributeOfType<DescriptionAttribute>().Description;</example>
    public static T GetAttributeOfType<T>(this Enum enumVal) where T : System.Attribute
    {
        var type = enumVal.GetType();
        var memInfo = type.GetMember(enumVal.ToString());
        IEnumerable<Attribute> attributes = memInfo[0].GetCustomAttributes(typeof(T), false);
        return (T)attributes?.ToArray()[0];
    }
}

其他回答

我实现了这个扩展方法来从枚举值中获取描述。它适用于所有类型的枚举。

public static class EnumExtension
{
    public static string ToDescription(this System.Enum value)
    {
        FieldInfo fi = value.GetType().GetField(value.ToString());
        var attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
        return attributes.Length > 0 ? attributes[0].Description : value.ToString();
    }
}

如果你想要完整的名单你可以这样做

typeof (PharmacyConfigurationKeys).GetFields()
        .Where(x => x.GetCustomAttributes(false).Any(y => typeof(DescriptionAttribute) == y.GetType()))
        .Select(x => ((DescriptionAttribute)x.GetCustomAttributes(false)[0]).Description);

朋友们,如果有帮助的话,我将与你们分享我的解决方案: Custom属性的定义:

    [AttributeUsage(AttributeTargets.Field,AllowMultiple = false)]
public class EnumDisplayName : Attribute
{
    public string Name { get; private set; }
    public EnumDisplayName(string name)
    {
        Name = name;
    }
}

现在因为我需要它在HtmlHelper扩展的HtmlHelper定义内:

public static class EnumHelper
{
    public static string EnumDisplayName(this HtmlHelper helper,EPriceType priceType)
    {
        //Get every fields from enum
        var fields = priceType.GetType().GetFields();
        //Foreach field skipping 1`st fieldw which keeps currently sellected value
        for (int i = 0; i < fields.Length;i++ )
        {
            //find field with same int value
            if ((int)fields[i].GetValue(priceType) == (int)priceType)
            {
                //get attributes of found field
                var attributes = fields[i].GetCustomAttributes(false);
                if (attributes.Length > 0)
                {
                    //return name of found attribute
                    var retAttr = (EnumDisplayName)attributes[0];
                    return retAttr.Name;
                }
            }
        }
        //throw Error if not found
        throw new Exception("Błąd podczas ustalania atrybutów dla typu ceny allegro");
    }
}

希望能有所帮助

或者,你可以这样做:

Dictionary<FunkyAttributesEnum, string> description = new Dictionary<FunkyAttributesEnum, string>()
    {
      { FunkyAttributesEnum.NameWithoutSpaces1, "Name With Spaces1" },
      { FunkyAttributesEnum.NameWithoutSpaces2, "Name With Spaces2" },
    };

并使用以下语句获取描述:

string s = description[FunkyAttributesEnum.NameWithoutSpaces1];

在我看来,这是一种更有效的方式去做你想要完成的事情,因为不需要思考。

模型

我们用这个模型来充实我们的价值观

public class MemberTypeModel : IDto
{
    public string MemberAttributeName { get; set; }
    public string MemberName { get; set; }
    public int MemberValue { get; set; }
}

Enum

我们的目标是枚举

public enum MemberType
{
    [FieldText("Yönetim Kurul Üyesi")]
    BoardManager = 0,

    [FieldText("Temsilci")]
    Representative = 1,

    [FieldText("Üye")]
    Member = 2
}

辅助方法

我们将使用helper方法来获取自定义属性对象

public T GetMemberCustomText<T>(MemberType memberType) where T : Attribute
{
    var enumType = memberType.GetType();
    var name = Enum.GetName(enumType, memberType);
    return enumType.GetField(name).GetCustomAttributes(false).OfType<T>().SingleOrDefault();
}

Get方法

首先,我们提取枚举值并将它们转换为枚举类型。然后,通过Linq选择查询我们知道;

MemberAttributeName字段与helper方法, 带有Enum的MemberName字段。GetName方法, 将MemberValue字段转换为int类型, 我们把它填好,然后变成一个清单。


public List<MemberTypeModel> GetMemberTypes()
{
    var memberTypes = Enum.GetValues(typeof(MemberType))
        .Cast<MemberType>()
        .Select(et => new MemberTypeModel
        {
            MemberAttributeName = GetMemberCustomText<FieldText>(et).Text,
            MemberName = Enum.GetName(et.GetType(), et),
            MemberValue = (int)et
        }).ToList();
    return memberTypes;
}