我想知道是否能夠獲取枚舉值而不是枚舉自己的屬性? 例如,假設我有如下枚舉: 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;