我有一个枚举,我希望以特殊方式呈现为字符串:
public enum FailureDescription
{
MemoryFailure,
Fragmentation,
SegmentationFault
}
我想将该枚举的值打印如下:FailureDescription.MemoryFailure.ToString() - > Memory Failure
我能这样做吗?怎么样?实现ToString?
答案 0 :(得分:2)
您可以编写自己的扩展方法:
public static string ToFormattedText(this MyEnum value)
{
var stringVal = value.ToString();
var bld = new StringBuilder();
for (var i = 1; i < stringVal.Length; i++)
{
if (char.IsUpper(stringVal[i]))
{
bld.Append(" ");
}
bld.Append(stringVal[i]);
}
return bld.ToString();
}
如果您希望方法适用于所有枚举,只需将MyEnum
替换为Enum
。
用法:
var test = MyEnum.SampleName.ToFormattedText();
考虑缓存 - 每次构建字符串都不是很有效。
答案 1 :(得分:0)
您还可以使用简单正则表达式&amp; linq混合物提取和连接词:
var withSpaces =
Regex
.Matches(
FailureDescription.MemoryFailureTest.ToString(),
@"([A-Z][a-z]+)(?=[A-Z]|$)")
.Cast<Match>()
.Select(m => m.Groups[1].Value)
.Aggregate((str, next) => (str = str + " " + next));
其中:
([A-Z][a-z]+)(?=[A-Z]|$)
匹配以大写字母开头的单词,直到找到下一个大写字母或字符串结尾:DEMO at regex101
.Select(m => m.Groups[1].Value)
从组1中选择匹配的值
.Aggregate((str, next) => (str = str + " " + next));
连接单词并在它们之间插入一个空格。
答案 2 :(得分:0)
使用Description属性来清空枚举值。我建议为资源添加resx
文件,以便您可以更轻松地进行本地化。如果你硬编码&#34;内存失败&#34;,那么能够将其改为另一种语言就会变得更加繁重(正如Hans Passant在评论中提到的那样)。
public enum FailureDescription
{
[Description("Memory Failure")] //hardcoding English
MemoryFailure,
[Description(MyStringsResourceFile.FragmentationDescription)] //reading from a resx file makes localisation easier
Fragmentation,
[Description(MyStringsResourceFile.SegmentationFaultDescription)]
SegmentationFault
}
然后,您可以创建方法或扩展方法(如图所示)来读取Description
值。
public static class Extensions
{
public static string GetDescription(this Enum value)
{
FieldInfo fi = value.GetType().GetField(value.ToString());
DescriptionAttribute[] attributes =
(DescriptionAttribute[])fi.GetCustomAttributes(
typeof(DescriptionAttribute),
false);
if (attributes != null &&
attributes.Length > 0)
return attributes[0].Description;
else
return value.ToString();
}
}
然后调用这样的方法
Console.WriteLine(FailureDescription.MemoryFailure.GetDescription());
答案 3 :(得分:0)
这是我一直使用的实用工具之一。 @HansPassant在他的评论中提出了关于本地化的一个好点。
此代码考虑了资源文件。在具有两个参数的属性中,第一个参数是资源文件中的密钥,其中第二个参数是资源的命名空间。
结帐git repo https://github.com/seanpaul/EnumExtensions
public enum TestEnum
{
//You can pass what ever string value you want
[StringValue("From Attribute")]
FromAttribute = 1,
//If localizing, you can use resource files
//First param is Key in resource file, second is namespace for Resources.
[StringValue("Test", "EnumExtensions.Tests.Resources")]
FromResource = 2,
//or don't mention anything and it will use built-in ToString
BuiltInToString = 3
}
[Test ()]
public void GetValueFromAttribute ()
{
var testEnum = TestEnum.FromAttribute;
Assert.AreEqual ("From Attribute", testEnum.GetStringValue ());
}
[Test ()]
public void GetValueFromResourceFile ()
{
var testEnum = TestEnum.FromResource;
Assert.AreEqual ("From Resource File", testEnum.GetStringValue ());
}
答案 4 :(得分:0)
此扩展方法将为您完成:
public static string ToFormattedText(this FailureDescription value)
{
return new string(value.ToString()
.SelectMany(c =>
char.IsUpper(c)
? new [] { ' ', c }
: new [] { c })
.ToArray()).Trim();
}
答案 5 :(得分:0)
遵循DRY和KISS原则的优雅解决方案是使用Humanizer:
"Memory Failure".DehumanizeTo<EnumUnderTest>(); // Returns FailureDescription.MemoryFailure.
"Fragmentation".DehumanizeTo<EnumUnderTest>(); // Returns FailureDescription.Fragmentation.
"Segmentation Fault".DehumanizeTo<EnumUnderTest>(); // Returns FailureDescription.SegmentationFault.