How to get an IEnumerable<string> of enum values attributes?

I have a StringValue attribute for enums values, so I could attach a description to each value:

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

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

And that is how I use it:

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

    [StringValue("Software Engineering")]
    SoftwareEngineering,

    // ... additional values follow.
}

I have a method that retrieves the StringValue given the enum value:

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

I want to have another method that gets an enum (the enum itself, not a value) and retrieves an IEnumerable using the GetStringValue method. I am not sure how to accomplish that. How could a method like this look like?


Edit: this question is not a duplicate of How to get C# Enum description from value?. I know how to get an enum attribute value, and I actually have a method in the question that does exactly that. My question is how to enumerate all the attributes in an enum.


The most straightforward way to do this is with a generic, though you could always pass in an instance of your specific Enum , get its type, then return the StringValue values for all its values:

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

Notes:

  • There is no where TEnum : Enum constraint in c#. Restricting TEnum to be struct, IConvertible, IComparable, IFormattable is mostly sufficient.

  • That being said, there is a cunning trick to apply an enum constraint which is shown in this answer to Enum type constraints in C# by SLaks. (I didn't use it in this answer though since it's really very cunning.)

  • As noted in @EdPlunkett's comment you need to pass value.ToString() to type.GetField() since you're getting the field corresponding to that specific incoming enum value.

  • Sample fiddle


    这应该工作:

    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);
        }
    }
    
    链接地址: http://www.djcxy.com/p/91544.html

    上一篇: 我应该如何将字符串转换为C#中的枚举?

    下一篇: 如何获得枚举值属性的IEnumerable <string>?