可能的重复: 通过描述属性查找枚举值

我有一个通用的扩展方法,从Enum中获得Description属性:

enum Animal
{
    [Description("")]
    NotSet = 0,

    [Description("Giant Panda")]
    GiantPanda = 1,

    [Description("Lesser Spotted Anteater")]
    LesserSpottedAnteater = 2
}

public static string GetDescription(this Enum value)
{            
    FieldInfo field = value.GetType().GetField(value.ToString());

    DescriptionAttribute attribute
            = Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute))
                as DescriptionAttribute;

    return attribute == null ? value.ToString() : attribute.Description;
}

所以我可以做…

string myAnimal = Animal.GiantPanda.GetDescription(); // = "Giant Panda"

现在,我试着在另一个方向上算出等效函数,就像……

Animal a = (Animal)Enum.GetValueFromDescription("Giant Panda", typeof(Animal));

当前回答

应该是相当直截了当的,它只是你以前的方法相反;

public static int GetEnumFromDescription(string description, Type enumType)
{
    foreach (var field in enumType.GetFields())
    {
        DescriptionAttribute attribute
            = Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute))as DescriptionAttribute;
        if(attribute == null)
            continue;
        if(attribute.Description == description)
        {
            return (int) field.GetValue(null);
        }
    }
    return 0;
}

用法:

Console.WriteLine((Animal)GetEnumFromDescription("Giant Panda",typeof(Animal)));

其他回答

应该是相当直截了当的,它只是你以前的方法相反;

public static int GetEnumFromDescription(string description, Type enumType)
{
    foreach (var field in enumType.GetFields())
    {
        DescriptionAttribute attribute
            = Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute))as DescriptionAttribute;
        if(attribute == null)
            continue;
        if(attribute.Description == description)
        {
            return (int) field.GetValue(null);
        }
    }
    return 0;
}

用法:

Console.WriteLine((Animal)GetEnumFromDescription("Giant Panda",typeof(Animal)));

你不能扩展Enum,因为它是一个静态类。您只能扩展类型的实例。考虑到这一点,你必须自己创建一个静态方法来完成这个任务;下面应该工作时结合你现有的方法GetDescription:

public static class EnumHelper
{
    public static T GetEnumFromString<T>(string value)
    {
        if (Enum.IsDefined(typeof(T), value))
        {
            return (T)Enum.Parse(typeof(T), value, true);
        }
        else
        {
            string[] enumNames = Enum.GetNames(typeof(T));
            foreach (string enumName in enumNames)
            {  
                object e = Enum.Parse(typeof(T), enumName);
                if (value == GetDescription((Enum)e))
                {
                    return (T)e;
                }
            }
        }
        throw new ArgumentException("The value '" + value 
            + "' does not match a valid enum name or description.");
    }
}

它的用法是这样的:

Animal giantPanda = EnumHelper.GetEnumFromString<Animal>("Giant Panda");

这个解决方案工作得很好,除非您有一个Web服务。

您需要执行以下操作,因为Description属性不可序列化。

[DataContract]
public enum ControlSelectionType
{
    [EnumMember(Value = "Not Applicable")]
    NotApplicable = 1,
    [EnumMember(Value = "Single Select Radio Buttons")]
    SingleSelectRadioButtons = 2,
    [EnumMember(Value = "Completely Different Display Text")]
    SingleSelectDropDownList = 3,
}

public static string GetDescriptionFromEnumValue(Enum value)
{
        EnumMemberAttribute attribute = value.GetType()
            .GetField(value.ToString())
            .GetCustomAttributes(typeof(EnumMemberAttribute), false)
            .SingleOrDefault() as EnumMemberAttribute;
        return attribute == null ? value.ToString() : attribute.Value;
}
public static class EnumEx
{
    public static T GetValueFromDescription<T>(string description) where T : Enum
    {
        foreach(var field in typeof(T).GetFields())
        {
            if (Attribute.GetCustomAttribute(field,
            typeof(DescriptionAttribute)) is DescriptionAttribute attribute)
            {
                if (attribute.Description == description)
                    return (T)field.GetValue(null);
            }
            else
            {
                if (field.Name == description)
                    return (T)field.GetValue(null);
            }
        }

        throw new ArgumentException("Not found.", nameof(description));
        // Or return default(T);
    }
}

用法:

var panda = EnumEx.GetValueFromDescription<Animal>("Giant Panda");

您需要遍历Animal中的所有枚举值,并返回与所需描述匹配的值。