将枚举转换为具有空格的字符串

问题描述 投票:2回答:6

我有一个枚举,我想使用特殊方式将其表示为字符串:

public enum FailureDescription
{
   MemoryFailure,
   Fragmentation,
   SegmentationFault
}

我想按如下方式打印该枚举的值:FailureDescription.MemoryFailure.ToString() - > Memory Failure我可以那样做吗?怎么样?实现ToString?

c# enums tostring
6个回答
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();

考虑缓存-每次构建字符串都不有效。


0
投票

您还可以使用simple正则表达式和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));

DEMO at ideone.com

其中:

([A-Z][a-z]+)(?=[A-Z]|$)

匹配以大写字母开头的单词,直到找到下一个大写字母或字符串结尾:DEMO at regex101

.Select(m => m.Groups[1].Value)

从组1中选择匹配的值

.Aggregate((str, next) => (str = str + " " + next));

连接单词并在单词之间插入空格。


0
投票

使用Description属性装饰枚举值。我建议为资源添加resx文件,以便您可以更轻松地进行本地化。如果您对“ Memory Failure”进行了硬编码,则可以将其更改为另一种语言(如注释中提到的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());

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 ());
}

0
投票

此扩展方法将为您完成:

public static string ToFormattedText(this FailureDescription value)
{
    return new string(value.ToString()
        .SelectMany(c =>
            char.IsUpper(c)
            ? new [] { ' ', c }
            : new [] { c })
        .ToArray()).Trim();
}

0
投票

遵循DRYKISS原理的优雅解决方案是使用Humanizer

"Memory Failure".DehumanizeTo<EnumUnderTest>(); // Returns FailureDescription.MemoryFailure.
"Fragmentation".DehumanizeTo<EnumUnderTest>(); // Returns FailureDescription.Fragmentation.
"Segmentation Fault".DehumanizeTo<EnumUnderTest>(); // Returns FailureDescription.SegmentationFault.
© www.soinside.com 2019 - 2024. All rights reserved.