我想知道是否有可能获得枚举值的属性,而不是枚举本身?例如,假设我有以下枚举:

using System.ComponentModel; // for DescriptionAttribute

enum FunkyAttributesEnum
{
    [Description("Name With Spaces1")]
    NameWithoutSpaces1,    
    [Description("Name With Spaces2")]
    NameWithoutSpaces2
}

我想要的是给定枚举类型,产生枚举字符串值及其描述的二元组。

价值很简单:

Array values = System.Enum.GetValues(typeof(FunkyAttributesEnum));
foreach (int value in values)
    Tuple.Value = Enum.GetName(typeof(FunkyAttributesEnum), value);

但我如何获得描述属性的值,以填充Tuple.Desc?如果属性属于枚举本身,我可以想到如何做到这一点,但我不知道如何从枚举的值中获得它。


当前回答

除了AdamCrawford响应之外,我还进一步创建了一个更专门的扩展方法来获取它的描述。

public static string GetAttributeDescription(this Enum enumValue)
{
    var attribute = enumValue.GetAttributeOfType<DescriptionAttribute>();
    return attribute == null ? String.Empty : attribute.Description;
} 

因此,要获得描述,您可以使用原始扩展方法as

string desc = myEnumVariable.GetAttributeOfType<DescriptionAttribute>().Description

或者你可以简单地调用这里的扩展方法:

string desc = myEnumVariable.GetAttributeDescription();

这应该会使您的代码更具可读性。

其他回答

这个扩展方法将使用枚举值的XmlEnumAttribute获得枚举值的字符串表示形式。如果没有XmlEnumAttribute,则返回到枚举. tostring()。

public static string ToStringUsingXmlEnumAttribute<T>(this T enumValue)
    where T: struct, IConvertible
{
    if (!typeof(T).IsEnum)
    {
        throw new ArgumentException("T must be an enumerated type");
    }

    string name;

    var type = typeof(T);

    var memInfo = type.GetMember(enumValue.ToString());

    if (memInfo.Length == 1)
    {
        var attributes = memInfo[0].GetCustomAttributes(typeof(System.Xml.Serialization.XmlEnumAttribute), false);

        if (attributes.Length == 1)
        {
            name = ((System.Xml.Serialization.XmlEnumAttribute)attributes[0]).Name;
        }
        else
        {
            name = enumValue.ToString();
        }
    }
    else
    {
        name = enumValue.ToString();
    }

    return name;
}

这应该能满足你的需要。

try
{
  var enumType = typeof(FunkyAttributesEnum);
  var memberInfos = 
  enumType.GetMember(FunkyAttributesEnum.NameWithoutSpaces1.ToString());
  var enumValueMemberInfo = memberInfos.FirstOrDefault(m => 
  m.DeclaringType == enumType);
  var valueAttributes = 
  enumValueMemberInfo.GetCustomAttributes(typeof(DescriptionAttribute), false);
  var description = ((DescriptionAttribute)valueAttributes[0]).Description;
}
catch
{
    return FunkyAttributesEnum.NameWithoutSpaces1.ToString()
}

感谢Bryan Rowe和AdamCrawford的回答!

但是如果有人需要方法来获取描述(而不是扩展),你可以使用它:

string GetEnumDiscription(Enum EnumValue)
        {
            var type = EnumValue.GetType();
            var memInfo = type.GetMember(EnumValue.ToString());
            var attributes = memInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);
            return (attributes.Length > 0) ? ((DescriptionAttribute)attributes[0]).Description : null;
        }

朋友们,如果有帮助的话,我将与你们分享我的解决方案: Custom属性的定义:

    [AttributeUsage(AttributeTargets.Field,AllowMultiple = false)]
public class EnumDisplayName : Attribute
{
    public string Name { get; private set; }
    public EnumDisplayName(string name)
    {
        Name = name;
    }
}

现在因为我需要它在HtmlHelper扩展的HtmlHelper定义内:

public static class EnumHelper
{
    public static string EnumDisplayName(this HtmlHelper helper,EPriceType priceType)
    {
        //Get every fields from enum
        var fields = priceType.GetType().GetFields();
        //Foreach field skipping 1`st fieldw which keeps currently sellected value
        for (int i = 0; i < fields.Length;i++ )
        {
            //find field with same int value
            if ((int)fields[i].GetValue(priceType) == (int)priceType)
            {
                //get attributes of found field
                var attributes = fields[i].GetCustomAttributes(false);
                if (attributes.Length > 0)
                {
                    //return name of found attribute
                    var retAttr = (EnumDisplayName)attributes[0];
                    return retAttr.Name;
                }
            }
        }
        //throw Error if not found
        throw new Exception("Błąd podczas ustalania atrybutów dla typu ceny allegro");
    }
}

希望能有所帮助

或者,你可以这样做:

Dictionary<FunkyAttributesEnum, string> description = new Dictionary<FunkyAttributesEnum, string>()
    {
      { FunkyAttributesEnum.NameWithoutSpaces1, "Name With Spaces1" },
      { FunkyAttributesEnum.NameWithoutSpaces2, "Name With Spaces2" },
    };

并使用以下语句获取描述:

string s = description[FunkyAttributesEnum.NameWithoutSpaces1];

在我看来,这是一种更有效的方式去做你想要完成的事情,因为不需要思考。