从枚举属性获取枚举

Rub*_*man 33 .net c# enums attributes custom-attributes

我有

public enum Als 
{
    [StringValue("Beantwoord")] Beantwoord = 0,
    [StringValue("Niet beantwoord")] NietBeantwoord = 1,
    [StringValue("Geselecteerd")] Geselecteerd = 2,
    [StringValue("Niet geselecteerd")] NietGeselecteerd = 3,
}
Run Code Online (Sandbox Code Playgroud)

public class StringValueAttribute : Attribute
{
    private string _value;

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

    public string Value
    {
        get { return _value; }
    }
}
Run Code Online (Sandbox Code Playgroud)

我想将我从组合框中选择的项的值放入int:

int i = (int)(Als)Enum.Parse(typeof(Als), (string)cboAls.SelectedValue); //<- WRONG
Run Code Online (Sandbox Code Playgroud)

这是可能的,如果是的话,怎么样?(StringValue匹配从组合框中选择的值).

djd*_*d87 21

这是一个帮助方法,应该指向正确的方向.

protected Als GetEnumByStringValueAttribute(string value)
{
    Type enumType = typeof(Als);
    foreach (Enum val in Enum.GetValues(enumType))
    {
        FieldInfo fi = enumType.GetField(val.ToString());
        StringValueAttribute[] attributes = (StringValueAttribute[])fi.GetCustomAttributes(
            typeof(StringValueAttribute), false);
        StringValueAttribute attr = attributes[0];
        if (attr.Value == value)
        {
            return (Als)val;
        }
    }
    throw new ArgumentException("The value '" + value + "' is not supported.");
}
Run Code Online (Sandbox Code Playgroud)

要调用它,只需执行以下操作:

Als result = this.GetEnumByStringValueAttribute<Als>(ComboBox.SelectedValue);
Run Code Online (Sandbox Code Playgroud)

这可能不是最好的解决方案,因为它与之相关Als并且您可能希望使此代码可重用.您可能想要从我的解决方案中删除代码以返回属性值,然后只是Enum.Parse在问题中使用.

  • 该解决方案可以轻松更改为通用.只需将所有出现的'Als`更改为`T`,并在方法中添加一个名为`T`的类型参数. (9认同)

Oli*_*ver 11

我正在使用Microsoft 的DescriptionAttribute和以下扩展方法:

public static string GetDescription(this Enum value)
{
    if (value == null)
    {
        throw new ArgumentNullException("value");
    }

    string description = value.ToString();
    FieldInfo fieldInfo = value.GetType().GetField(description);
    DescriptionAttribute[] attributes =
       (DescriptionAttribute[])
     fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false);

    if (attributes != null && attributes.Length > 0)
    {
        description = attributes[0].Description;
    }
    return description;
}
Run Code Online (Sandbox Code Playgroud)

  • OP问道,因为他想从字符串枚举而不是enum的字符串,但是这对我帮助很大,谢谢! (7认同)

jos*_*rry 6

这里有一些我用于这个目的的扩展方法,我已经重写了这些以使用你的StringValueAttribute,但像Oliver我在我的代码中使用DescriptionAttribute.

    public static T FromEnumStringValue<T>(this string description) where T : struct {
        Debug.Assert(typeof(T).IsEnum);

        return (T)typeof(T)
            .GetFields()
            .First(f => f.GetCustomAttributes(typeof(StringValueAttribute), false)
                         .Cast<StringValueAttribute>()
                         .Any(a => a.Value.Equals(description, StringComparison.OrdinalIgnoreCase))
            )
            .GetValue(null);
    }
Run Code Online (Sandbox Code Playgroud)

在.NET 4.5中,这可以稍微简单一点:

    public static T FromEnumStringValue<T>(this string description) where T : struct {
        Debug.Assert(typeof(T).IsEnum);

        return (T)typeof(T)
            .GetFields()
            .First(f => f.GetCustomAttributes<StringValueAttribute>()
                         .Any(a => a.Value.Equals(description, StringComparison.OrdinalIgnoreCase))
            )
            .GetValue(null);
    }
Run Code Online (Sandbox Code Playgroud)

要调用它,只需执行以下操作:

Als result = ComboBox.SelectedValue.FromEnumStringValue<Als>();
Run Code Online (Sandbox Code Playgroud)

相反,这是一个从枚举值中获取字符串的函数:

    public static string StringValue(this Enum enumItem) {
        return enumItem
            .GetType()
            .GetField(enumItem.ToString())
            .GetCustomAttributes<StringValueAttribute>()
            .Select(a => a.Value)
            .FirstOrDefault() ?? enumItem.ToString();
    }
Run Code Online (Sandbox Code Playgroud)

并称之为:

string description = Als.NietBeantwoord.StringValue()
Run Code Online (Sandbox Code Playgroud)