更改枚举菜单名称格式[C#]

时间:2018-09-28 20:23:02

标签: c# c#-4.0 enums console-application

我在格式化格式方面遇到了问题,特别是我想如何在控制台窗口中显示枚举项。

截至目前,Menu方法如下所示显示枚举中的项目:

[1] CreateCustomer
[2] CreateAccount
[3] SetAccountBalance
[4] DisplayAccount Balance
[5] Exit

我要努力做到的是在每个菜单选项之间添加适当的空格。例如, “创建客户”到“创建客户”,“设置帐户余额”到“设置帐户余额”。

菜单选择枚举

enum MenuSelection
{
   CreateCustomer = 1,
   CreateAccount = 2,
   SetAccountBalance = 3,
   DisplayAccountBalance = 4,
   Exit = 5,
   MaxMenuSelection = 5,
}

显示菜单方法

public static void Menu()
{
  for (int i = 1; i <= (int)MenuSelection.MaxMenuSelection; i++)
  {
     Console.WriteLine($"[{i}] {((MenuSelection)i).ToString()}");
  }
}

有什么建议吗?

6 个答案:

答案 0 :(得分:3)

我将使用DictionarykeyMenuSelection,而value包含您的客户显示字符串。

Dictionary<MenuSelection, string> dict = new Dictionary<MenuSelection, string>();
dict.Add(MenuSelection.CreateCustomer, "Create Customer");
dict.Add(MenuSelection.CreateAccount, "Create Account");
dict.Add(MenuSelection.SetAccountBalance, "Set Account Balance");
dict.Add(MenuSelection.DisplayAccountBalance, "Display Account Balance");
dict.Add(MenuSelection.Exit, "Exit");

string showValue = string.Empty;
for (int i = 1; i <= (int)MenuSelection.MaxMenuSelection; i++)
{
    if (dict.TryGetValue((MenuSelection)i, out showValue))
    {
        Console.WriteLine($"[{i}] { showValue}");
    }           
}

答案 1 :(得分:1)

一种方法是使用显示属性:

enum MenuSelection
{
   [Display(Name = "Create Customer")]
   CreateCustomer = 1,
   [Display(Name = "Create Account")]
   CreateAccount = 2,
   ...
}

但是要获得其价值并不像应该的那么容易。您可以在How to get the Display Name Attribute of an Enum member via MVC razor code?

中找到它

我自己使用的另一种方式是我编写的函数,该函数在每个大写字母之前添加一个空格:

public static class Exts
{ 
    public static string CapitalSplit(this string x)
    {
         return Regex.Replace(x, "([a-z])([A-Z])", "$1 $2").Trim();
    }
}

然后您可以像使用它一样

 for (int i = 1; i <= (int)MenuSelection.MaxMenuSelection; i++)
 {
     Console.WriteLine($"[{i}] {((MenuSelection)i).ToString().CapitalSplit()}");
 }

答案 2 :(得分:0)

您可以使用反射来获取Description属性(或Display属性)。在这里,我使用了扩展方法使其变得更简单:

class Program
{
    static void Main(string[] args)
    {
        for (int i = 1; i <= (int)MenuSelection.MaxMenuSelection; i++)
        {
            Console.WriteLine($"[{i}] {((MenuSelection)i).GetEnumDescription()}");
        }

        Console.ReadLine();
    }
}

public static class Extensions
{
    public static string GetEnumDescription(this MenuSelection m)
    {
        FieldInfo fi = m.GetType().GetField(m.ToString());

        DescriptionAttribute[] attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);

        return attributes != null && attributes.Length > 0 ? attributes[0].Description : m.ToString();
    }
}

public enum MenuSelection
{
    [Description("Create Customer")]
    CreateCustomer = 1,
    [Description("Create Account")]
    CreateAccount = 2,
    [Description("Set Account Balance")]
    SetAccountBalance = 3,
    [Description("Display Account Balance")]
    DisplayAccountBalance = 4,
    Exit = 5,
    MaxMenuSelection = 5,
}

结果:

[1] Create Customer
[2] Create Account
[3] Set Account Balance
[4] Display Account Balance
[5] Exit

答案 3 :(得分:0)

您可以这样做

using System;
using System.Linq;
using System.Collections.Generic;

public class Program
{
    enum MenuSelection
    {
        CreateCustomer = 1,
        CreateAccount = 2,
        SetAccountBalance = 3,
        DisplayAccountBalance = 4,
        Exit = 5,
        MaxMenuSelection = 5,
    }

    public static void Main()
    {
        Enum
            .GetNames(typeof(MenuSelection))
            .Select(name => new 
            { 
                name, 
                index = (int)Enum.Parse(typeof(MenuSelection), name, true) 
            })
            .Select(kv => $"[{kv.index}] " + String.Join(" ", SplitByCamelCase(kv.name)))
            .Select(item => 
            {
                Console.WriteLine(item);
                return true;
            })
            .ToList();
    }

    public static bool IsLower(char ch) 
    {
        return ch >= 'a' && ch <= 'z';
    }

    public static string Head(string str)
    {
        return new String(
                    str
                        .Take(1)
                        .Concat(
                            str
                                .Skip(1)
                                .TakeWhile(IsLower)
                        )
                        .ToArray()
                );
    }

    public static string Tail(string str)
    {
        return new String(str.Skip(Head(str).Length).ToArray());
    }

    public static IEnumerable<string> SplitByCamelCase(string str) 
    {
        if (str.Length == 0) 
            return new List<string>();

        return 
            new List<string> 
            { 
                Head(str) 
            }
            .Concat(
                SplitByCamelCase(
                    Tail(str)
                )
            );
    }
}

结果:

[1] Create Customer
[2] Create Account
[3] Set Account Balance
[4] Display Account Balance
[5] Exit
[5] Max Menu Selection

See sample online

答案 4 :(得分:0)

这是非常快速和肮脏的。但是,这样做的好处是您可以创建任何enum类型的任何菜单。

它根据大小写(上/下)转换来分隔单词。除了您的MaxMenuSelection之外,它都有效。与其将其放入您的枚举中,不如将其设为返回GetValues()。Length(请参见下文)的模板(枚举类型)函数:

下面显示的wherewhere T : struct,因为我使用的编译器不支持where T : System.Enum,这会更好,但需要最新的编译器。

  public static string SeparateWords(string enumName)
  {
      var buffer = new StringBuilder();
      var wasLower = false;
      foreach (var c in enumName)
      {
          if (wasLower && char.IsUpper(c))
          {
              buffer.Append(' ');
          }

          buffer.Append(c);
          wasLower = char.IsLower(c);
      }

      return buffer.ToString();
  }

  public static void DisplayMenu<T>() where T : struct //should be System.Enum if possible
  {
      var enumType = typeof(T);
      var names = Enum.GetNames(enumType);
      var values = Enum.GetValues(enumType) as int[];
      for (var i = 0; i < names.Length; ++i)
      {
          Console.WriteLine($"[{values[i]}] {SeparateWords(names[i])}");
      }
  }

我得到以下输出:

[1] Create Customer
[2] Create Account
[3] Set Account Balance
[4] Display Account Balance
[5] Exit
[5] Max Menu Selection

当我这样称呼时:

 EnumTest.DisplayMenu<MenuSelection>();

而且,您可以通过执行以下操作获得“最大菜单选择”:

public static int MaxMenuSelection<T>() where T : struct
{
    return Enum.GetValues(typeof(T)).Length;
}

答案 5 :(得分:-1)

为什么不做简单的事情,并在单词之间添加_?

然后您可以执行以下操作:

    enum MenuSelection
    {
        Create_Customer = 1,
        Create_Account = 2,
        Set_Account_Balance = 3,
        Display_Account_Balance = 4,
        Exit = 5,
        MaxMenuSelection = 5,
    }
    public static void Menu()
    {
        for (int i = 1; i <= (int)MenuSelection.MaxMenuSelection; i++)
        {
            Console.WriteLine($"[{i}] {((MenuSelection)i).ToString().Replace("_"," ")}");
        }
    }

结果如下:

 [1] Create Customer
 [2] Create Account
 [3] Set Account Balance
 [4] Display Account Balance
 [5] Exit