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

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?如果属性属于枚举本身,我可以想到如何做到这一点,但我不知道如何从枚举的值中获得它。


当前回答

或者,你可以这样做:

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

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

string s = description[FunkyAttributesEnum.NameWithoutSpaces1];

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

其他回答

这段代码应该为任何枚举提供了一个不错的扩展方法,使您可以检索泛型属性。我相信它与上面的lambda函数不同,因为它使用起来更简单,而且稍微-你只需要传入泛型类型。

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><![CDATA[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());
        var attributes = memInfo[0].GetCustomAttributes(typeof(T), false);
        return (attributes.Length > 0) ? (T)attributes[0] : null;
    }
}

用法如下:

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

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

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();
    }
}

利用一些较新的c#语言特性,你可以减少行数:

public static TAttribute GetEnumAttribute<TAttribute>(this Enum enumVal) where TAttribute : Attribute
{
    var memberInfo = enumVal.GetType().GetMember(enumVal.ToString());
    return memberInfo[0].GetCustomAttributes(typeof(TAttribute), false).OfType<TAttribute>().FirstOrDefault();
}

public static string GetEnumDescription(this Enum enumValue) => enumValue.GetEnumAttribute<DescriptionAttribute>()?.Description ?? enumValue.ToString();

这就是我在不使用。net core 3.1的自定义helper或扩展的情况下解决它的方法。

public enum YourEnum
{
    [Display(Name = "Suryoye means Arameans")]
    SURYOYE = 0,
    [Display(Name = "Oromoye means Syriacs")]
    OROMOYE = 1,
}

剃须刀

@using Enumerations

foreach (var name in Html.GetEnumSelectList(typeof(YourEnum)))
{
    <h1>@name.Text</h1>
}

从enum中获取字典。

public static IDictionary<string, int> ToDictionary(this Type enumType)
{
    return Enum.GetValues(enumType)
    .Cast<object>()
    .ToDictionary(v => ((Enum)v).ToEnumDescription(), k => (int)k); 
}

现在把它叫做…

var dic = typeof(ActivityType).ToDictionary();

枚举描述Ext方法

public static string ToEnumDescription(this Enum en) //ext method
{
    Type type = en.GetType();
    MemberInfo[] memInfo = type.GetMember(en.ToString());
    if (memInfo != null && memInfo.Length > 0)
    {
        object[] attrs = memInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);
        if (attrs != null && attrs.Length > 0)
            return ((DescriptionAttribute)attrs[0]).Description;
    }
    return en.ToString();
}

public enum ActivityType
{
    [Description("Drip Plan Email")]
    DripPlanEmail = 1,
    [Description("Modification")]
    Modification = 2,
    [Description("View")]
    View = 3,
    [Description("E-Alert Sent")]
    EAlertSent = 4,
    [Description("E-Alert View")]
    EAlertView = 5
}