枚举元素的可读字符串






4.43/5 (11投票s)
使用枚举确实有助于提高可读性,但枚举中的值必须符合变量命名规则,以便理解。这很好,直到你需要将枚举值显示给用户。这个技巧展示了如何将可读字符串与每个枚举元素关联并访问。
我使用相当多的
enum
块,但我讨厌使用匹配的switch
语句来将它们渲染成可读字符串(或者使用字符串数组来做同样的事情,尤其是在我的enum
可能只有六个元素,并且值固定在1和十六进制8000之间时)。所以我设计了这个方法来消除这个问题,并将描述性文本与enum
元素定义一起保留。这通过使用反射来访问可以应用于任何控件的DescriptionAttribute,并且也可以应用于任何其他对象 - 包括单个变量,如果你愿意的话。 (这可能有点过头,但嘿!这是你的软件!)。声明这两个静态方法/// <summary> /// Get description of a enum value /// See DescriptionAttribute for enum element /// </summary> /// <remarks> /// Returns the human readable string set as the DescriptionAttribute /// for an enum element. /// If the DescriptionAttribute has not been set, returns the enum element name /// </remarks> /// <example> /// public enum MyEnum /// { /// [DescriptionAttribute("A Human readable string")] /// AMachineReadableEnum, /// } /// ... /// string s = MyEnum.AMachineReadableEnum.ToString(); /// s += " : " + GetDescription(MyEnum.AMachineReadableEnum); /// MessageBox.Show(s); /// /// would display "AMachineReadableEnum : A Human readable string" /// </example> /// <seealso cref="ValueOf<T>"/> /// <param name="value">Enum element with human readable string</param> /// <returns>Human readable string for enum element</returns> public static string GetDescription(Enum value) { // Get information on the enum element FieldInfo fi = value.GetType().GetField(value.ToString()); // Get description for elum element DescriptionAttribute[] attributes = (DescriptionAttribute[]) fi.GetCustomAttributes(typeof(DescriptionAttribute), false); if (attributes.Length > 0) { // DescriptionAttribute exists - return that return attributes[0].Description; } // No Description set - return enum element name return value.ToString(); } /// <summary> /// Get an enum element from its human readable string. /// </summary> /// <remarks> /// Returns the enum element for a human readable string /// If the DescriptionAttribute has not been set, throws an /// ArgumentException /// </remarks> /// <example> /// public enum MyEnum /// { /// [DescriptionAttribute("A Human readable string")] /// AMachineReadableEnum, /// } /// ... /// MyEnum me = ValueOf<MyEnum>("A Human readable string"); /// MyEnum me = MyEnum.AMachineReadableEnum; /// /// would be equivelent /// </example> /// <exception cref="ArgumentException if description not found to match an enum element" /// <seealso cref="GetDescription"/> /// <typeparam name="T">Enum the element will belong to</typeparam> /// <param name="description">Human readable string assocuiated with enum element</param> /// <returns>Enum element</returns> public static T ValueOf<T>(string description) { Type enumType = typeof(T); string[] names = Enum.GetNames(enumType); foreach (string name in names) { if (GetDescription((Enum) Enum.Parse(enumType, name)).Equals(description, StringComparison.InvariantCultureIgnoreCase)) { // Found it! return (T) Enum.Parse(enumType, name); } } // No such description in this enum throw new ArgumentException("The string is not a description or value of the specified enum."); }现在声明你的枚举,并使用DescriptionAttribute
public enum MyEnum { [DescriptionAttribute("A Human readable string")] AMachineReadableEnum, [DescriptionAttribute("Another Human readable string")] ASecondMachineReadableEnum, }然后尝试一下
private void ShowItWorking() { string s = ""; s = GetDescription(MyEnum.AMachineReadableEnum); s += " : " + MyEnum.AMachineReadableEnum.ToString(); s += " : " + ValueOf<MyEnum>("a human READABLE string"); MyEnum me = ValueOf<MyEnum>("A HUMAN readable STRING"); s += " : " + ((int) ).ToString(); MessageBox.Show(s); }