Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将枚举转换为具有空格的字符串_C#_Enums_Tostring - Fatal编程技术网

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

C# 将枚举转换为具有空格的字符串,c#,enums,tostring,C#,Enums,Tostring,我有一个枚举,我想用特殊方式将其表示为字符串: public enum FailureDescription { MemoryFailure, Fragmentation, SegmentationFault } 我想按如下方式打印该枚举的值:FailureDescription.MemoryFailure.ToString->Memory Failure 我可以这样做吗?怎样实现ToString?您可以编写自己的扩展方法: public static string ToFo

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

public enum FailureDescription
{
   MemoryFailure,
   Fragmentation,
   SegmentationFault
}
我想按如下方式打印该枚举的值:FailureDescription.MemoryFailure.ToString->Memory Failure
我可以这样做吗?怎样实现ToString?

您可以编写自己的扩展方法:

public static string ToFormattedText(this MyEnum value)
{
    var stringVal = value.ToString();   
    var bld = new StringBuilder();

    for (var i = 0; i < stringVal.Length; i++)
    {
        if (char.IsUpper(stringVal[i]))
        {
            bld.Append(" ");
        }

        bld.Append(stringVal[i]);
    }

    return bld.ToString();
}
考虑缓存-每次构建字符串都不可能有效。

您还可以使用简单的regex和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));
匹配以大写字母开头的单词,直到找到下一个大写字母或字符串结尾:

从组1中选择匹配的值

.Aggregate((str, next) => (str = str + " " + next));
连接单词并在单词之间插入空格。

使用该属性对枚举值进行解压缩。我建议为资源添加一个resx文件,这样您可以更轻松地进行本地化。如果您硬编码了内存故障,那么将其转换为另一种语言(如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
}
然后可以创建一个方法或扩展方法,如图所示,以读取描述值

然后像这样调用该方法

Console.WriteLine(FailureDescription.MemoryFailure.GetDescription());

下面是我一直在使用的实用程序之一@汉帕桑在他的评论中提出了本地化的好观点

此代码考虑了资源文件。在具有两个参数的属性中,第一个参数是资源文件中的键,其中第二个参数是资源的命名空间

签出git回购协议


此扩展方法将为您完成以下操作:

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

遵循以下原则和原则的优雅解决方案将使用:


正如我所知,默认情况下,在枚举上进行设置。注意:使用[Flags]attribute@L奥里诺达-是的。如何添加空间?请参阅答案。坏主意,当您需要本地化应用程序时,您将永远为此后悔。只需使用一个查找表,我明白了。谢谢我想要更多的内置方式。没有内置方式。您不能覆盖枚举的ToString。没有内置的方法以这种方式添加空格。为什么建议的解决方案不能使用?@pwas您可以使用var i=1;。。。取消i>0的测试。@AndrewMorton是的,好主意。谢谢……如果resx文件不那么难维护就好了;-]哈哈,这不是本地化最有趣的部分
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
}
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());
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 ());
}
public static string ToFormattedText(this FailureDescription value)
{
    return new string(value.ToString()
        .SelectMany(c =>
            char.IsUpper(c)
            ? new [] { ' ', c }
            : new [] { c })
        .ToArray()).Trim();
}
"Memory Failure".DehumanizeTo<EnumUnderTest>(); // Returns FailureDescription.MemoryFailure.
"Fragmentation".DehumanizeTo<EnumUnderTest>(); // Returns FailureDescription.Fragmentation.
"Segmentation Fault".DehumanizeTo<EnumUnderTest>(); // Returns FailureDescription.SegmentationFault.