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

Posted

技术标签:

【中文标题】如何获取枚举值属性的 IEnumerable<string>?【英文标题】:How to get an IEnumerable<string> of enum values attributes? 【发布时间】:2017-12-19 18:37:59 【问题描述】:

我有一个用于枚举值的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。我不确定如何做到这一点。这样的方法怎么可能是这样的?


编辑:这个问题不是 How to get C# Enum description from value? 的重复问题。我知道如何获取枚举属性值,实际上我在问题中有一个方法可以做到这一点。我的问题是如何枚举枚举中的所有属性。

【问题讨论】:

你的意思是你想要一个泛型方法GetStringValues&lt;TEnum&gt;()? 您可以使用现有的DescriptionAttribute 代替您自己的自定义属性。对于枚举,Enum.GetValues(typeof(EnumType)).Cast&lt;EnumType&gt;().Select(/*call your method*/) 另外,错字:FieldInfo fieldInfo = type.GetField(value.ToString()); -- 你传递的是type.ToString(),而不是value.ToString() @Sipo 这对我有用。 dbc 刚刚发布了我将要建议的解决方案,所以我节省了一些打字时间,只是对他投了赞成票。 @Sipo 只是元数据,它经常用于枚举值。它不会造成任何伤害。当然,出于同样的原因,自己编写也没有什么坏处。 【参考方案1】:

最直接的方法是使用泛型,但您始终可以传入特定 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# 中由SLaks 显示。 (虽然我没有在这个答案中使用它,因为它真的很狡猾。)

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

示例fiddle

【讨论】:

完美运行。谢谢。【参考方案2】:

这应该可行:

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

【讨论】:

谢谢!我选择了@dbc 的答案,因为它更适合我的程序,但您的答案似乎也不错。

以上是关于如何获取枚举值属性的 IEnumerable<string>?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 LINQ 从 DataTable 中以 IEnumerable<MODEL> 形式获取数据?

从 IEnumerable<T> 中获取不同的项目

如何通过传入枚举值和属性类型来获取枚举的自定义属性?

如何从表达式主体成员返回空的 IEnumerable [重复]

如何获取枚举的自定义属性值?

获取 IEnumerable<T> 计数的最佳方法