我想知道是否能够获取枚举值而不是枚举自己的属性? 例如,假设我有如下枚举: ide
using System.ComponentModel; // for DescriptionAttribute enum FunkyAttributesEnum { [Description("Name With Spaces1")] NameWithoutSpaces1, [Description("Name With Spaces2")] NameWithoutSpaces2 }
我想要的是枚举类型,产生2个元组的枚举字符串值及其描述。 this
价值很容易: spa
Array values = System.Enum.GetValues(typeof(FunkyAttributesEnum)); foreach (int value in values) Tuple.Value = Enum.GetName(typeof(FunkyAttributesEnum), value);
可是,如何获取描述属性的值以填充Tuple.Desc? 我能够考虑若是Attribute属于枚举自己,那么该怎么作,可是我对如何从枚举的值中获取它感到困惑。 code
您还能够定义一个枚举值,例如Name_Without_Spaces
,当须要描述时,请使用Name_Without_Spaces.ToString().Replace('_', ' ')
用空格替换下划线。 ip
我实现了此扩展方法,以从枚举值获取描述。 它适用于全部枚举。 字符串
public static class EnumExtension { public static string ToDescription(this System.Enum value) { FieldInfo fi = value.GetType().GetField(value.ToString()); var attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false); return attributes.Length > 0 ? attributes[0].Description : value.ToString(); } }
除了AdamCrawford响应以外 ,我还建立了一种更专业的扩展方法,将其提要以获取描述。 get
public static string GetAttributeDescription(this Enum enumValue) { var attribute = enumValue.GetAttributeOfType<DescriptionAttribute>(); return attribute == null ? String.Empty : attribute.Description; }
所以,为了得到描述,您能够使用原始扩展方法做为 string
string desc = myEnumVariable.GetAttributeOfType<DescriptionAttribute>().Description
或者您能够简单地将扩展方法调用为: it
string desc = myEnumVariable.GetAttributeDescription();
但愿能够使您的代码更具可读性。 io
这是从Display属性获取信息的代码。 它使用通用方法检索属性。 若是找不到该属性,它将枚举值转换为字符串,而pascal / camel大小写转换为标题大小写( 在此处得到代码)
public static class EnumHelper { // Get the Name value of the Display attribute if the // enum has one, otherwise use the value converted to title case. public static string GetDisplayName<TEnum>(this TEnum value) where TEnum : struct, IConvertible { var attr = value.GetAttributeOfType<TEnum, DisplayAttribute>(); return attr == null ? value.ToString().ToSpacedTitleCase() : attr.Name; } // Get the ShortName value of the Display attribute if the // enum has one, otherwise use the value converted to title case. public static string GetDisplayShortName<TEnum>(this TEnum value) where TEnum : struct, IConvertible { var attr = value.GetAttributeOfType<TEnum, DisplayAttribute>(); return attr == null ? value.ToString().ToSpacedTitleCase() : attr.ShortName; } /// <summary> /// Gets an attribute on an enum field value /// </summary> /// <typeparam name="TEnum">The enum type</typeparam> /// <typeparam name="T">The type of the attribute you want to retrieve</typeparam> /// <param name="value">The enum value</param> /// <returns>The attribute of type T that exists on the enum value</returns> private static T GetAttributeOfType<TEnum, T>(this TEnum value) where TEnum : struct, IConvertible where T : Attribute { return value.GetType() .GetMember(value.ToString()) .First() .GetCustomAttributes(false) .OfType<T>() .LastOrDefault(); } }
这是用于转换为标题大小写的字符串的扩展方法:
/// <summary> /// Converts camel case or pascal case to separate words with title case /// </summary> /// <param name="s"></param> /// <returns></returns> public static string ToSpacedTitleCase(this string s) { //https://stackoverflow.com/a/155486/150342 CultureInfo cultureInfo = Thread.CurrentThread.CurrentCulture; TextInfo textInfo = cultureInfo.TextInfo; return textInfo .ToTitleCase(Regex.Replace(s, "([a-z](?=[A-Z0-9])|[A-Z](?=[A-Z][a-z]))", "$1 ")); }
这应该作您须要的。
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;