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

时间:2017-12-19 18:37:59

标签: c# enums

我有枚举值的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;
}

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

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

2 个答案:

答案 0 :(得分: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约束。限制TEnumstruct, IConvertible, IComparable, IFormattable 足够。

  • 话虽如此,但有一个狡猾的伎俩要求enum this answer Enum type constraints in C# SLaks显示value.ToString()约束。 (我在这个答案中没有使用它,因为它非常狡猾。)

  • 正如@ EdPlunkett评论中所述,您需要将type.GetField()传递给enum,因为您获得了与该特定传入 final RelativeLayout rootLayout = (RelativeLayout)findViewById(R.id.myRootLayout); final Random random = new Random(3); //generates 0 to 2 (as you set seed of 3 digits starting from 0) final List<Integer> myBackgroundImages = new ArrayList<Integer>(); myBackgroundImages.add(R.drawable.add_person); myBackgroundImages.add(R.drawable.add_photo_album); myBackgroundImages.add(R.drawable.add_key_box); rootLayout.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { rootLayout.setBackground(myBackgroundImages.get(random.nextInt()); //will be 0, 1, or 2 } }); 相对应的字段值。

示例fiddle

答案 1 :(得分: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);
    }
}