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