首页 文章

如何获取枚举值属性的IEnumerable <string>?

提问于
浏览
0

我有枚举值的 StringValue 属性,所以我可以为每个值附加一个描述:

public class StringValueAttribute : Attribute
{
    public string Value { get; private set; }

    public StringValueAttribute(string value)
    {
        Value = value;
    }
}

这就是我使用它的方式:

enum Group
{
    [StringValue("Computer Science")]
    ComputerScience,

    [StringValue("Software Engineering")]
    SoftwareEngineering,

    // ... additional values follow.
}

我有一个方法,在给定枚举值的情况下检索 StringValue

public static string GetStringValue(Enum value)
{
    Type type = value.GetType();
    FieldInfo fieldInfo = type.GetField(type.ToString());
    StringValueAttribute[] attributes = fieldInfo.GetCustomAttributes(typeof(StringValueAttribute), false) as StringValueAttribute[];

    string stringValue = null;
    if (attributes.Length > 0)
    {
        stringValue = attributes[0].Value;
    }

    return stringValue;
}

我想要另一个获取枚举的方法(枚举本身,而不是值)并使用 GetStringValue 方法检索 IEnumerable . 我不知道如何做到这一点 . 这样的方法怎么样?


Edit: 此问题与How to get C# Enum description from value?不重复 . 我知道如何获取枚举属性值,我实际上在问题中有一个方法就是这样做的 . 我的问题是如何枚举枚举中的所有属性 .

2 回答

  • 2

    最直接的方法是使用泛型,尽管您可以随时传入特定 Enum 的实例,获取其类型,然后为其所有值返回 StringValue 值:

    public static class EnumExtensions
    {
        public static IEnumerable<string> GetStringValues<TEnum>() where TEnum : struct, IConvertible, IComparable, IFormattable
        {
            return Enum.GetValues(typeof(TEnum))
                .Cast<Enum>()
                .Select(e => e.GetStringValue())
                .ToList();
        }
    
        public static IEnumerable<string> GetStringValuesOfType(Enum value)
        {
            return Enum.GetValues(value.GetType())
                .Cast<Enum>()
                .Select(e => e.GetStringValue())
                .ToList();
        }
    
        public static string GetStringValue(this Enum value)
        {
            Type type = value.GetType();
            FieldInfo fieldInfo = type.GetField(value.ToString());
            StringValueAttribute[] attributes = fieldInfo.GetCustomAttributes(typeof(StringValueAttribute), false) as StringValueAttribute[];
    
            string stringValue = null;
            if (attributes.Length > 0)
            {
                stringValue = attributes[0].Value;
            }
    
            return stringValue;
        }
    }
    

    笔记:

    • c#中没有 where TEnum : Enum 约束 . 将 TEnum 限制为 struct, IConvertible, IComparable, IFormattable 基本上就足够了 .

    • 即便如此,有一个狡猾的技巧来应用 enum 约束,该约束在this answer中由Enum type constraints in C#显示为Enum type constraints in C# . (我真的很狡猾 . )

    • 如@ EdPlunkett的评论中所述,您需要将 value.ToString() 传递给 type.GetField() ,因为您获得的字段对应于该特定的传入 enum 值 .

    样品fiddle

  • 1

    这应该工作:

    static void Main(string[] args)
    {
        foreach (var item in GetStringNames<Group>())
        {
            Console.WriteLine(item);
        }
    }
    public static string GetStringValue(Enum value)
    {
        Type type = value.GetType();
        FieldInfo fieldInfo = type.GetField(value.ToString());
        StringValueAttribute[] attributes = fieldInfo.GetCustomAttributes(typeof(StringValueAttribute), false) as StringValueAttribute[];
    
        string stringValue = null;
        if (attributes.Length > 0)
        {
            stringValue = attributes[0].Value;
        }
    
        return stringValue;
    }
    
    public static IEnumerable<string> GetStringNames<T>()
    {
        var type = typeof(T);
    
        if (type.IsEnum == false)
        {
            throw new ArgumentException("T must be an Enum type");
        }
    
        var values = type.GetEnumValues();
    
        foreach (var item in values)
        {
            yield return GetStringValue((Enum)item);
        }
    }
    

相关问题