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

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


当前回答

我已经创建了一个扩展方法,它将返回c#中枚举中所有元素的描述。

public static List<string> GetAllEnumDescriptions(this Type enumType)
    {
        try
        {
            var enumList = Enum.GetValues(enumType).Cast<Enum>().ToList();
            List<string> result = new List<string>();
            foreach (var enumItem in enumList)
            {
                result.Add(enumItem.EnumDescription());
            }
            return result;
        }
        catch (Exception ex)
        {
            return new List<string>();
        }
    }

此方法将使用内置的EnumDescription()扩展方法添加枚举中元素的描述。

其他回答

下面是从Display属性获取信息的代码。它使用泛型方法检索属性。如果没有找到该属性,它将枚举值转换为字符串,将pascal/camel大小写转换为标题大小写(此处获得的代码)

public static class EnumHelper
{
    // Get the Name value of the Display attribute if the   
    // enum has one, otherwise use the value converted to title case.  
    public static string GetDisplayName<TEnum>(this TEnum value)
        where TEnum : struct, IConvertible
    {
        var attr = value.GetAttributeOfType<TEnum, DisplayAttribute>();
        return attr == null ? value.ToString().ToSpacedTitleCase() : attr.Name;
    }

    // Get the ShortName value of the Display attribute if the   
    // enum has one, otherwise use the value converted to title case.  
    public static string GetDisplayShortName<TEnum>(this TEnum value)
        where TEnum : struct, IConvertible
    {
        var attr = value.GetAttributeOfType<TEnum, DisplayAttribute>();
        return attr == null ? value.ToString().ToSpacedTitleCase() : attr.ShortName;
    }

    /// <summary>
    /// Gets an attribute on an enum field value
    /// </summary>
    /// <typeparam name="TEnum">The enum type</typeparam>
    /// <typeparam name="T">The type of the attribute you want to retrieve</typeparam>
    /// <param name="value">The enum value</param>
    /// <returns>The attribute of type T that exists on the enum value</returns>
    private static T GetAttributeOfType<TEnum, T>(this TEnum value)
        where TEnum : struct, IConvertible
        where T : Attribute
    {

        return value.GetType()
                    .GetMember(value.ToString())
                    .First()
                    .GetCustomAttributes(false)
                    .OfType<T>()
                    .LastOrDefault();
    }
}

这是字符串转换为title case的扩展方法:

    /// <summary>
    /// Converts camel case or pascal case to separate words with title case
    /// </summary>
    /// <param name="s"></param>
    /// <returns></returns>
    public static string ToSpacedTitleCase(this string s)
    {
        //https://stackoverflow.com/a/155486/150342
        CultureInfo cultureInfo = Thread.CurrentThread.CurrentCulture;
        TextInfo textInfo = cultureInfo.TextInfo;
        return textInfo
           .ToTitleCase(Regex.Replace(s, 
                        "([a-z](?=[A-Z0-9])|[A-Z](?=[A-Z][a-z]))", "$1 "));
    }

感谢Bryan Rowe和AdamCrawford的回答!

但是如果有人需要方法来获取描述(而不是扩展),你可以使用它:

string GetEnumDiscription(Enum EnumValue)
        {
            var type = EnumValue.GetType();
            var memInfo = type.GetMember(EnumValue.ToString());
            var attributes = memInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);
            return (attributes.Length > 0) ? ((DescriptionAttribute)attributes[0]).Description : null;
        }

模型

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

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

这应该能满足你的需要。

try
{
  var enumType = typeof(FunkyAttributesEnum);
  var memberInfos = 
  enumType.GetMember(FunkyAttributesEnum.NameWithoutSpaces1.ToString());
  var enumValueMemberInfo = memberInfos.FirstOrDefault(m => 
  m.DeclaringType == enumType);
  var valueAttributes = 
  enumValueMemberInfo.GetCustomAttributes(typeof(DescriptionAttribute), false);
  var description = ((DescriptionAttribute)valueAttributes[0]).Description;
}
catch
{
    return FunkyAttributesEnum.NameWithoutSpaces1.ToString()
}

    public enum DataFilters
    {
        [Display(Name= "Equals")]
        Equals = 1,// Display Name and Enum Name are same 
        [Display(Name= "Does Not Equal")]
        DoesNotEqual = 2, // Display Name and Enum Name are different             
    }

在这个例子中它会产生错误1 "等于"

public static string GetDisplayName(this Enum enumValue)
    {
        var enumMember = enumValue.GetType().GetMember(enumValue.ToString()).First();
        return enumMember.GetCustomAttribute<DisplayAttribute>() != null ? enumMember.GetCustomAttribute<DisplayAttribute>().Name : enumMember.Name;
    }

如果它是相同的返回enum名称而不是显示名称因为 enumMember.GetCustomAttribute () 如果displayname和enum name相同,则返回null .....