有谁知道如何将枚举值转换为人类可读的值?
例如:
ThisIsValueA should be"This is Value A".
从某位Ian Horwill很久以前在博客文章中留下的vb代码片段转换为此代码……我已经在生产中成功使用了此代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| /// <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;')
从而:
1
| Console.WriteLine(Wordify(ThisIsValueA.ToString())); |
会回来的
与提供Description属性相比,它要简单得多,而且冗余程度也较低。
属性仅在需要提供间接层(问题未要求的地方)时才有用。
在C#中,Enums上的.ToString相对较慢,与GetType()。Name相当(它甚至可以在幕后使用)。
如果您的解决方案需要非常快速或高效,那么最好将转换缓存在静态字典中,然后从那里查找它们。
@Leon代码的一小部分改编以利用C#3。作为枚举的扩展,这确实有意义-如果您不想将所有枚举弄乱,则可以将其限制为特定类型。
1 2 3 4 5 6 7 8
| 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(); |
您可以继承System.Reflection的" Attribute"类来创建自己的" Description"类。像这样(从这里开始):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| 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));
}
}
} |
我见过的大多数示例都涉及用[Description]属性标记您的枚举值,并使用反射在值和描述之间进行"转换"。这是关于它的旧博客文章:
http://geekswithblogs.net/rakker/archive/2006/05/19/78952.aspx
您也可以看一下这篇文章:http://www.codeproject.com/KB/cs/enumdatabinding.aspx
它专门用于数据绑定,但是显示了如何使用属性来修饰枚举值,并提供了一种" GetDescription"方法来检索属性的文本。使用内置的description属性的问题在于该属性还有其他用途/用户,因此有可能该描述出现在您不希望出现的位置。自定义属性解决了该问题。
向每个枚举添加Description属性的另一种方法是创建扩展方法。重用亚当的" Coolness"枚举:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| public enum Coolness
{
NotSoCool,
Cool,
VeryCool,
SuperCool
}
public static class CoolnessExtensions
{
public static string ToString(this Coolness coolness)
{
switch (coolness)
{
case Coolness.NotSoCool:
return"Not so cool";
case Coolness.Cool:
return"Cool";
case Coolness.VeryCool:
return"Very cool";
case Coolness.SuperCool:
return Properties.Settings.Default["SuperCoolDescription"].ToString();
default:
throw new ArgumentException("Unknown amount of coolness", nameof(coolness));
}
}
} |
尽管这意味着描述与实际值相距甚远,但是它允许您使用本地化为每种语言打印不同的字符串,例如在我的VeryCool示例中。
我发现最好用低分来定义您的枚举值,因此ThisIsValueA将为This_Is_Value_A,然后您可以执行enumValue.toString()。Replace(" _",""),其中enumValue是您的变量。