如何用反射获取枚举值的所有描述?

Har*_*9pl 5 c# reflection ienumerable enums custom-attributes

所以我需要List<string>从我的enum

到目前为止,这是我所做的:

枚举定义

    [Flags]
    public enum ContractorType
    {
        [Description("Recipient")]
        RECIPIENT = 1,
        [Description("Deliver")]
        DELIVER = 2,
        [Description("Recipient / Deliver")]
        RECIPIENT_DELIVER = 4
    }
Run Code Online (Sandbox Code Playgroud)

HelperClass与方法来做我需要的:

public static class EnumUtils
{
    public static IEnumerable<string> GetDescrptions(Type enumerator)
    {
        FieldInfo[] fi = enumerator.GetFields();

        List<DescriptionAttribute> attributes = new List<DescriptionAttribute>();
        foreach (var i in fi)
        {
            try
            {
                yield return attributes.Add(((DescriptionAttribute[])i.GetCustomAttributes(
                    typeof(DescriptionAttribute),
                    false))[0]);
            }
            catch { }
        }
        return new List<string>{"empty"};
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,在我yield重视的那一行中,我得到了一个NullReferenceException。我错过了什么?语法对我来说似乎还不错,但也许我忽略了某些内容?

编辑: 我在这里使用.net Framework 4.0。

Thi*_*lva 9

这个通用静态方法可以很好地获取 T 枚举类型的每个值的描述列表:

public static IEnumerable<string> GetDescriptions<T>()
{
    var attributes = typeof(T).GetMembers()
        .SelectMany(member => member.GetCustomAttributes(typeof (DescriptionAttribute), true).Cast<DescriptionAttribute>())
        .ToList();

    return attributes.Select(x => x.Description);
}
Run Code Online (Sandbox Code Playgroud)


Bru*_*oLM 5

我创建了这些扩展方法

public static class EnumExtender
{
    public static string GetDescription(this Enum enumValue)
    {
        string output = null;
        Type type = enumValue.GetType();
        FieldInfo fi = type.GetField(enumValue.ToString());
        var attrs = fi.GetCustomAttributes(typeof(DescriptionAttribute), false) as DescriptionAttribute[];
        if (attrs.Length > 0) output = attrs[0].Description;
        return output;
    }

    public static IDictionary<T, string> GetEnumValuesWithDescription<T>(this Type type) where T : struct, IConvertible
    {
        if (!type.IsEnum)
        {
            throw new ArgumentException("T must be an enumerated type");
        }

        return type.GetEnumValues()
                .OfType<T>()
                .ToDictionary(
                    key => key,
                    val => (val as Enum).GetDescription()
                );
    }
}
Run Code Online (Sandbox Code Playgroud)

用法

var stuff = typeof(TestEnum).GetEnumValuesWithDescription<TestEnum>();
Run Code Online (Sandbox Code Playgroud)

将返回一个Dictionary<TestEnum, string>,其中值作为键,描述作为值。如果您只想要一个列表,您可以更改.ToDictionary

.Select(o => (o as Enum).GetDescription())
.ToList()
Run Code Online (Sandbox Code Playgroud)


Yus*_*zun 0

它认为这可以解决您的问题。如果未实现,您可以返回null或抛出异常。这取决于你需要什么。

public DescriptionAttribute GetDescription(ContractorType contractorType)
{
     MemberInfo memberInfo = typeof(ContractorType).GetMember(contractorType.ToString())
                                          .FirstOrDefault();

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

    //return null;
    //or

    throw new NotImplementedException("There is no description for this enum");
}
Run Code Online (Sandbox Code Playgroud)

所以你将像这样使用它:

DescriptionAttribute attribute = GetDescription(ContractorType.RECIPIENT);
Run Code Online (Sandbox Code Playgroud)

抱歉,我没有阅读你的问题。以下是一些可用于获取所有描述字符串的代码:

 public IEnumerable<string> GetAllDescriptionInText()
 {
     List<string> descList = new List<string>();
     foreach (DescriptionAttribute desc in Enum.GetValues(typeof(DescriptionAttribute)))
     {
         descList.Add(GetDescription(desc).Value);
     }
     return descList;
 }
Run Code Online (Sandbox Code Playgroud)