C# 如何在c中改进我的菜单(控制台)#
我在控制台中创建了一个带有子菜单的菜单。一切正常,但我想知道是否有可能改进我的程序结构。简化它,使它更通用C# 如何在c中改进我的菜单(控制台)#,c#,menu,C#,Menu,我在控制台中创建了一个带有子菜单的菜单。一切正常,但我想知道是否有可能改进我的程序结构。简化它,使它更通用 class MainClass { public static void Main(string[] args) { MainMenu(); } public static void MainMenu() { Console.WriteLine("Main Menu"); Console.WriteL
class MainClass
{
public static void Main(string[] args)
{
MainMenu();
}
public static void MainMenu()
{
Console.WriteLine("Main Menu");
Console.WriteLine("--------------------");
Console.WriteLine("[1] Show activities");
Console.WriteLine("[2] Show teachers");
Console.WriteLine("[3] Show students");
Console.WriteLine("[4] Exit the program");
Console.WriteLine("--------------------\n");
Console.WriteLine("Please select an option from 1-4\n");
string choice = Console.ReadLine();
int number;
bool result = Int32.TryParse(choice, out number);
if (result)
{
Console.Clear();
SubMenu(number);
}
else
{
Console.WriteLine("Incorrect choice");
}
}
public static void SubMenu(int mainMenuChoice)
{
switch (mainMenuChoice)
{
case 1:
Console.WriteLine("Activities");
Console.WriteLine("[1] Show all activities");
Console.WriteLine("[2] Find a activity by his code");
Console.WriteLine("[3] Return Main Menu");
Console.WriteLine("[4] Exit the program");
Console.WriteLine("--------------------\n");
Console.WriteLine("Please select an option from 1-4\n");
break;
case 2:
Console.WriteLine("Teachers");
Console.WriteLine("[1] Show all teachers");
Console.WriteLine("[2] Find a teacher by his matricule");
Console.WriteLine("[3] Return Main Menu");
Console.WriteLine("[4] Exit the program");
Console.WriteLine("--------------------\n");
Console.WriteLine("Please select an option from 1-4\n");
break;
case 3:
Console.WriteLine("Students");
Console.WriteLine("[1] Show all students");
Console.WriteLine("[2] Find a student by his matricule");
Console.WriteLine("[3] Return Main Menu");
Console.WriteLine("[4] Exit the program");
Console.WriteLine("--------------------\n");
Console.WriteLine("Please select an option from 1-4\n");
break;
case 4:
Environment.Exit(0);
break;
}
string choice = Console.ReadLine();
int number;
bool result = Int32.TryParse(choice, out number);
if (result)
{
Action(mainMenuChoice, number);
}
else
{
Console.WriteLine("Incorrect choice");
}
}
public static void Action(int menu, int choice)
{
switch (menu)
{
case 1:
switch (choice)
{
case 1:
// Do Stuff
break;
case 2:
// Do Stuff
break;
case 3:
Console.Clear();
MainMenu();
break;
case 4:
Environment.Exit(0);
break;
}
break;
case 2:
switch (choice)
{
case 1:
// Do Stuff
break;
case 2:
// Do Stuff
break;
case 3:
Console.Clear();
MainMenu();
break;
case 4:
Environment.Exit(0);
break;
}
break;
case 3:
switch (choice)
{
case 1:
// Do Stuff
break;
case 2:
// Do Stuff
break;
case 3:
Console.Clear();
MainMenu();
break;
case 4:
Environment.Exit(0);
break;
}
break;
}
}
}
目前,如果我必须添加一个子菜单,我必须在MainMenu()函数中添加一行,我必须在SubMenu()函数中添加一个case,并尽可能多地添加此菜单的选项()。
只有一个子菜单是可以的,但如果我必须添加一打,它很快就会变得难以管理。
我可能需要学习一个或多个课程,但我对结构一无所知。我很快做了一些事情来演示解决问题的一种方法。我评论了大部分代码,但询问是否有不清楚的地方。对我来说,主要的优点是,您可以在一个地方将菜单声明为对象。在我的代码中,我已经在Main方法中显式地完成了这项工作,但是您可以很容易地编写一个工厂方法来为您生成菜单
class Program
{
//represents a line/option in a menu
class MenuItem
{
// displayed in the menu
public string Text { get; set; }
//is there a sub menu
public bool HasSubMenu { get; set; }
// if there's a submenu, what's its id
public int? SubMenuId { get; set; }
//if there isn't a sub menu, what should we do
public Action Action { get; set; }
}
//represents one menu i.e. a collection of options
class Menu
{
public Menu()
{
MenuItems = new List<MenuItem>();
}
public int MenuId { get; set; }
public List<MenuItem> MenuItems { get; set; }
public string Title { get; set; }
public void PrintToConsole()
{
foreach (MenuItem item in MenuItems)
{
Console.WriteLine(MenuItems.IndexOf(item) + " : " + item.Text);
}
}
}
//represents all the menus
class MenuCollection
{
public MenuCollection()
{
Menus = new List<Menu>();
}
public List<Menu> Menus { get; set; }
public void ShowMenu(int id)
{
//get the menu we want to display and call its PrintToConsole method
var currentMenu = Menus.Where(m => m.MenuId == id).Single();
currentMenu.PrintToConsole();
//wait for user input
string choice = Console.ReadLine();
int choiceIndex;
//once we have the users selection make sure its an integer and in range of our menu options
//if not then show an error message and re-display the menu
if (!int.TryParse(choice, out choiceIndex) || currentMenu.MenuItems.Count < choiceIndex || choiceIndex < 0)
{
Console.Clear();
Console.WriteLine("Invalid selection - try again");
ShowMenu(id);
}
else
{
// if the selection is good, then retrieve the corresponding menu item
var menuItemSelected = currentMenu.MenuItems[choiceIndex];
// if there's a sub menu then display it
if (menuItemSelected.HasSubMenu)
{
Console.Clear();
ShowMenu(menuItemSelected.SubMenuId.Value);
}
// otherwise perform whatever action we need
else
{
menuItemSelected.Action();
}
}
}
}
static void Main(string[] args)
{
// build a collection of menus
// can have as deep a structure as you like
// give each menu a unique integer MenuId
// link to other menus by setting HasSubMenu to true, and the SubMenuId to the MenuId of the menu you wish to link to
// or, set HasSubMenu to false, and have an Action performed when the menuitem is selected
MenuCollection collection = new MenuCollection()
{
Menus =
{
new Menu()
{
MenuId = 1,
MenuItems =
{
new MenuItem()
{
Text = "Go to sub menu",
HasSubMenu = true,
SubMenuId = 2
},
new MenuItem()
{
Text = "Print Action",
HasSubMenu = false,
Action = () =>
{
Console.WriteLine("I printed from an action");
}
}
}
},
new Menu()
{
MenuId = 2,
MenuItems =
{
new MenuItem()
{
Text = "Sub menu option 1",
HasSubMenu = false,
Action = () =>
{
Console.WriteLine("Printed from a sub menu");
}
},
new MenuItem()
{
Text = "Back to the top menu",
HasSubMenu = true,
SubMenuId = 1
}
}
}
}
};
collection.ShowMenu(1);
Console.ReadLine();
}
}
类程序
{
//表示菜单中的行/选项
类菜单项
{
//显示在菜单中
公共字符串文本{get;set;}
//有副菜单吗
公共bool HasSubMenu{get;set;}
//如果有子菜单,它的id是什么
公共int?子菜单id{get;set;}
//如果没有子菜单,我们该怎么办
公共操作动作{get;set;}
}
//表示一个菜单,即选项集合
班级菜单
{
公共菜单()
{
MenuItems=新列表();
}
public int MenuId{get;set;}
公共列表菜单项{get;set;}
公共字符串标题{get;set;}
public void PrintToConsole()
{
foreach(菜单项中的菜单项)
{
Console.WriteLine(MenuItems.IndexOf(item)+“:”+item.Text);
}
}
}
//表示所有菜单
类菜单集合
{
公共菜单集合()
{
菜单=新列表();
}
公共列表菜单{get;set;}
公共无效显示菜单(int id)
{
//获取要显示的菜单并调用其PrintToConsole方法
var currentMenu=Menus.Where(m=>m.MenuId==id).Single();
currentMenu.PrintToConsole();
//等待用户输入
字符串选项=Console.ReadLine();
int choiceIndex;
//一旦我们有了用户选择,确保它是一个整数并且在我们的菜单选项范围内
//如果没有,则显示错误消息并重新显示菜单
如果(!int.TryParse(choice,out choiceIndex)| | current menu.MenuItems.Count
{
Console.WriteLine(“我从一个动作打印出来”);
}
}
}
},
新菜单()
{
MenuId=2,
菜单项=
{
新菜单项()
{
Text=“子菜单选项1”,
HasSubMenu=false,
动作=()=>
{
Console.WriteLine(“从子菜单打印”);
}
},
新菜单项()
{
Text=“返回顶部菜单”,
HasSubMenu=true,
子菜单ID=1
}
}
}
}
};
收藏。展示菜单(1);
Console.ReadLine();
}
}
我最近制作了很多小型CLI工具,我只是充实了一些活动,但下面是一个我通常喜欢对许多分支菜单/逻辑采用的方法的示例:
class Program
{
static T GetChoice<T>(List<Tuple<string, T>> choices)
{
var i = 1;
choices.ForEach(x => Console.WriteLine($"[{i++}]: {x.Item1}"));
var choiceIndex = int.Parse(Console.ReadLine());
return choices[choiceIndex - 1].Item2;
}
static void Main(string[] args)
{
Console.WriteLine("Main Menu: ");
var choices = new List<Tuple<string, Action>>()
{
new Tuple<string, Action>("Show Activities", ShowActivities),
new Tuple<string, Action>("Show Teachers", ShowTeachers),
new Tuple<string, Action>("Show Students", ShowStudents),
new Tuple<string, Action>("Exit", Exit),
};
GetChoice(choices)();
}
static void ShowActivities()
{
Console.WriteLine("Activities: ");
var choices = new List<Tuple<string, Action>>()
{
new Tuple<string, Action>("Show all activities", ShowAllActivities),
new Tuple<string, Action>("Find activity by code", FindActivityByCode),
new Tuple<string, Action>("Return to main menu", () => { Main(null); }),
new Tuple<string, Action>("Exit the program", Exit),
};
GetChoice(choices)();
}
static void ShowTeachers()
{
Console.WriteLine("Teachers: ");
var choices = new List<Tuple<string, Action>>();
}
static void ShowStudents()
{
Console.WriteLine("Students: ");
var choices = new List<Tuple<string, Action>>();
}
static void ShowAllActivities()
{
//Do stuff
}
static void FindActivityByCode()
{
//Do stuff
}
static void ReturnToMainMenu()
{
//Do stuff
}
static void Exit()
{
Environment.Exit(0);
}
}
类程序
{
静态T GetChoice(列表选项)
{
var i=1;
choices.ForEach(x=>Console