关于c#:如何获得IEnumerable< string>

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

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

1
2
3
4
5
6
7
8
9
public class StringValueAttribute : Attribute
{
    public string Value { get; private set; }

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

我就是这样使用它的:

1
2
3
4
5
6
7
8
9
10
enum Group
{
    [StringValue("Computer Science")]
    ComputerScience,

    [StringValue("Software Engineering")]
    SoftwareEngineering,

    // ... additional values follow.
}

我有一个方法可以检索给定枚举值的StringValue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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。我不知道如何做到这一点。像这样的方法怎么可能看起来像?

编辑:这个问题不是如何从值中获取C枚举描述的副本?.I知道如何获取枚举属性值,实际上我有一个方法可以做到这一点。我的问题是如何枚举枚举中的所有属性。


最简单的方法是使用泛型,尽管您可以在特定Enum的实例中传递,获取其类型,然后返回其所有值的StringValue值:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
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约束,如这个答案所示,它可以通过slaks在C中对枚举类型的约束。(不过这个答案我没有用,因为它真的很狡猾。)

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

样板小提琴


这应该有效:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
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);
    }
}