我在格式化格式方面遇到了问题,特别是我想如何在控制台窗口中显示枚举项。
截至目前,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()}");
}
}
有什么建议吗?
答案 0 :(得分:3)
我将使用Dictionary
,key
是MenuSelection
,而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
答案 4 :(得分:0)
这是非常快速和肮脏的。但是,这样做的好处是您可以创建任何enum
类型的任何菜单。
它根据大小写(上/下)转换来分隔单词。除了您的MaxMenuSelection之外,它都有效。与其将其放入您的枚举中,不如将其设为返回GetValues()。Length(请参见下文)的模板(枚举类型)函数:
下面显示的where
是where 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