将枚举转换为人类可读的值
有谁知道如何将枚举值转换为人类可读的值?
例如:
ThisIsValueA should be "This is Value A".
解决方案
回答
我所见过的大多数示例都涉及用[Description]属性标记枚举值,并使用反射在值和描述之间进行"转换"。这是关于它的旧博客文章:
http://geekswithblogs.net/rakker/archive/2006/05/19/78952.aspx
回答
我们也可以看一下这篇文章:http://www.codeproject.com/KB/cs/enumdatabinding.aspx
它专门用于数据绑定,但是显示了如何使用属性来修饰枚举值,并提供了一种" GetDescription"方法来检索属性的文本。使用内置的description属性的问题是该属性还有其他用途/用户,因此有可能该描述出现在我们不希望出现的位置。自定义属性解决了该问题。
回答
我们可以继承System.Reflection的" Attribute"类来创建自己的" Description"类。像这样(从这里开始):
using System; using System.Reflection; namespace FunWithEnum { enum Coolness : byte { [Description("Not so cool")] NotSoCool = 5, Cool, // since description same as ToString no attr are used [Description("Very cool")] VeryCool = NotSoCool + 7, [Description("Super cool")] SuperCool } class Description : Attribute { public string Text; public Description(string text) { Text = text; } } class Program { static string GetDescription(Enum en) { Type type = en.GetType(); MemberInfo[] memInfo = type.GetMember(en.ToString()); if (memInfo != null && memInfo.Length > 0) { object[] attrs = memInfo[0].GetCustomAttributes(typeof(Description), false); if (attrs != null && attrs.Length > 0) return ((Description)attrs[0]).Text; } return en.ToString(); } static void Main(string[] args) { Coolness coolType1 = Coolness.Cool; Coolness coolType2 = Coolness.NotSoCool; Console.WriteLine(GetDescription(coolType1)); Console.WriteLine(GetDescription(coolType2)); } } }
回答
从某位Ian Horwill很久以前在博客文章中留下的vb代码片段转换为此代码...我已经在生产中成功使用了此代码。
/// <summary> /// Add spaces to separate the capitalized words in the string, /// i.e. insert a space before each uppercase letter that is /// either preceded by a lowercase letter or followed by a /// lowercase letter (but not for the first char in string). /// This keeps groups of uppercase letters - e.g. acronyms - together. /// </summary> /// <param name="pascalCaseString">A string in PascalCase</param> /// <returns></returns> public static string Wordify(string pascalCaseString) { Regex r = new Regex("(?<=[a-z])(?<x>[A-Z])|(?<=.)(?<x>[A-Z])(?=[a-z])"); return r.Replace(pascalCaseString, " ${x}"); }
(需要'使用System.Text.RegularExpressions;')
因此:
Console.WriteLine(Wordify(ThisIsValueA.ToString()));
会回来的
"This Is Value A".
与提供Description属性相比,它要简单得多,而且冗余程度也较低。
属性仅在需要提供间接层(问题未要求的地方)时才有用。
回答
我发现最好用低分来定义枚举值,因此ThisIsValueA将为This_Is_Value_A,然后我们可以执行enumValue.toString()。Replace(" _",""),其中enumValue是变量。
回答
在C#中,Enums上的.ToString相对较慢,与GetType()。Name相当(它甚至可以在内部使用)。
如果解决方案需要非常快速或者高效,那么最好将转换缓存在静态字典中,然后从那里查找它们。
@Leon代码的一小部分改编以利用C#3. 作为枚举的扩展,这确实是有道理的,如果我们不希望将所有枚举都弄乱,则可以将其限制为特定类型。
public static string Wordify(this Enum input) { Regex r = new Regex("(?<=[a-z])(?<x>[A-Z])|(?<=.)(?<x>[A-Z])(?=[a-z])"); return r.Replace( input.ToString() , " ${x}"); } //then your calling syntax is down to: MyEnum.ThisIsA.Wordify();