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

时间:2015-01-18 13:37:56

标签: c# enums tostring

我有一个枚举,我希望以特殊方式呈现为字符串:

public enum FailureDescription
{
   MemoryFailure,
   Fragmentation,
   SegmentationFault
}

我想将该枚举的值打印如下:FailureDescription.MemoryFailure.ToString() - > Memory Failure 我能这样做吗?怎么样?实现ToString?

6 个答案:

答案 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));

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

连接单词并在它们之间插入一个空格。

答案 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)

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

"Memory Failure".DehumanizeTo<EnumUnderTest>(); // Returns FailureDescription.MemoryFailure.
"Fragmentation".DehumanizeTo<EnumUnderTest>(); // Returns FailureDescription.Fragmentation.
"Segmentation Fault".DehumanizeTo<EnumUnderTest>(); // Returns FailureDescription.SegmentationFault.