问题描述
(C#) 我正在开发一个类似于 RedBox 的程序,它将具有客户和经理功能.我只是想在开始实现更多功能之前让所有菜单正常工作,但我遇到了一个我似乎无法理解的错误.我的问题似乎出在 CustomerMenu() 方法和 MainMenu() 方法中.我已经添加了我拥有的所有内容,以便您可以获得完整的图片.感谢任何帮助,因为我仍然有点新,所以感谢任何提示,谢谢.
(C#) I am working on a program that is similar to RedBox which will have customer and manager functions. I am just trying to get all the menu's working correctly before I begin implementing more functions, but I am encountering an error that I can not seem to understand. My issue seems to be in the CustomerMenu() method and in the MainMenu() method. I have added all that I have so you can get the full picture. Any help is appreciated as I am still somewhat new so any tips are appreciated, thank you.
MainMenu(); Console.ReadKey(); } static void MainMenu() { int userChoice = MainMenuChoice(); // Reading in the userChoice with the MenuChoice method if (userChoice == 3) // if user enters 3, the program ends { Console.WriteLine("Thank you, Goodbye!"); } while (userChoice != 3) { if (userChoice == 1) { Console.WriteLine("Welcome to the customer menu! "); // The customer menu is brought up if user enters 1 CustomerMenu(); } if (userChoice == 2) { Console.WriteLine("Welcome to the manager menu! "); // The manager menu is brought up if user enters 2 //ManagerMenu(); } userChoice = MainMenuChoice(); // program ends if (userChoice == 3) { Console.WriteLine("Thank you for visiting VideoMart at University Boulevard, Goodbye!"); } } } static int MainMenuChoice() { Console.WriteLine("-----------------------------------------------------------------------------------------------------------"); // introducing the user with the menu Console.WriteLine("Welcome to VideoMart at University Boulevard! At VideoMart you are able to rent a variety of movies from many genres such as action, family, horror, etc!"); Console.WriteLine(" Press 1 if you are a customer"); Console.WriteLine(" Press 2 if you are a manager"); Console.WriteLine(" Press 3 to Exit"); Console.WriteLine("-----------------------------------------------------------------------------------------------------------"); string choice = Console.ReadLine(); Console.WriteLine(); while (!(choice == "1" || choice == "2" || choice == "3")) // error checking { Console.WriteLine("Please try again"); Console.WriteLine("Press 1 if you are a customer"); Console.WriteLine("Press 2 if you are a manager"); Console.WriteLine("Press 3 to Exit"); choice = Console.ReadLine(); } return int.Parse(choice); } } static void CustomerMenu() { int customerChoice = CustomerMenuChoice(); // Reading in the customerChoice into the CustomerMenuChoice method if (customerChoice == 5) // if user enters 5, the program ends { Console.WriteLine("Thank you for using VideoMart!"); } while (customerChoice != 5) { if (customerChoice == 1) { Console.WriteLine("Press 1 to view movies available to rent. "); // this option gives the user the opportunity to view all movies available to rent //MoviesAvailable(); } if (customerChoice == 2) { Console.WriteLine("Press 2 to rent a movie. "); // this option gives the user the opportunity to rent a movie, with email address //RentMovie(); } if (customerChoice == 3) { Console.WriteLine("Press 3 to view a list of movies you currently have rented. "); // this option gives the user the opportunity to view movies a user currently has rented, with email address //RentMovie(); } if (customerChoice == 4) { Console.WriteLine("Press 4 to return a movie rented. "); // this option gives the user the opportunity to return a movie rented //RentMovie(); } customerChoice = CustomerMenuChoice(); if (customerChoice == 5) { Console.WriteLine("Thank you for visiting VideoMart at University Boulevard, Goodbye!"); } } } static int CustomerMenuChoice() { Console.WriteLine("-----------------------------------------------------------------------------------------------------------"); // introducing the user with the menu Console.WriteLine("Welcome to VideoMart at University Boulevard! Below is a list of actions that can be performed by customers!"); Console.WriteLine(" Press 1 to view movies available to rent."); Console.WriteLine(" Press 2 to rent a movie."); Console.WriteLine(" Press 3 to view a list of movies you currently have rented."); Console.WriteLine(" Press 4 to return a movie rented."); Console.WriteLine(" Press 5 to exit."); Console.WriteLine("-----------------------------------------------------------------------------------------------------------"); string customerChoice2 = Console.ReadLine(); Console.WriteLine(); while (!(customerChoice2 == "1" || customerChoice2 == "2" || customerChoice2 == "3" || customerChoice2 == "4") || customerChoice2 == "5") // error checking { Console.WriteLine(" Press 1 to view movies available to rent."); Console.WriteLine(" Press 2 to rent a movie."); Console.WriteLine(" Press 3 to view a list of movies you currently have rented."); Console.WriteLine(" Press 4 to return a movie rented."); Console.WriteLine(" Press 5 to exit."); customerChoice2 = Console.ReadLine(); } return int.Parse(customerChoice2); } }
推荐答案
使用平面菜单系统
您可以尝试更正并稍微重构一下.
You can try this corrected and a little refactored.
我们创建了一个获取用户选择的方法,因此不再需要重复代码.我们使用 uint 是因为选择是肯定的,并且使用 TryParse 来转换输入的字符串.出错时返回 0,所以这里没问题.
We created a method to get the user choice, so repeat code is no more needed. We use uint because choice is positive and TryParse to convert the inputed string. It returns 0 in case of error, so that's fine here.
我们还使用 lamda 来打印选择字符串以不重复它们.
Also we use a lamda to print the choices strings to not repeat them.
接下来我们使用 switch 来管理选择,以便代码更干净和可维护.
Next we use a switch to manage choice so the code is more clean and maintainable.
清除菜单之间的控制台,我们提供根菜单和子菜单之间的导航.
The console is cleared between menus and we offer navigation between root and sub menus.
未来的改进是使用运行这些表的自动菜单管理器创建菜单标题、选项和相关方法的表格.只是稍微复杂一点,但不要太多.这可以通过创建一些集合和一个 MenuManager 类来完成.有了这样的东西,你将拥有一个健壮的系统,代码很少,没有重复.
A future improvement is to create tables of menus headers, choices and associated methods... with a auto-menu manager that runs these tables. Just a little more complex but not too much. It can be done by creating some collections and a MenuManager class. With such thing, you will have a robust system with very few code and nothing repeated.
static void Test() { MainMenu(); }
static uint GetUserChoice(Action printMenu, int choiceMax) { uint choice = 0; Action getInput = () => { uint.TryParse(Console.ReadLine(), out choice); }; getInput(); while ( choice < 1 || choice > choiceMax ) { Console.WriteLine(); Console.WriteLine("Please try again"); printMenu(); getInput(); } return choice; }
static void MainMenu() { Action printMenu = () => { Console.WriteLine("Press 1 if you are a customer"); Console.WriteLine("Press 2 if you are a manager"); Console.WriteLine("Press 3 to Exit"); }; Console.Clear(); Console.WriteLine("-----------------------------------------------------------------------------------------------------------"); // introducing the user with the menu Console.WriteLine("Welcome to VideoMart at University Boulevard!"); Console.WriteLine("At VideoMart you are able to rent a variety of movies from many genres such as action, family, horror, etc!"); Console.WriteLine(); printMenu(); Console.WriteLine("-----------------------------------------------------------------------------------------------------------"); uint choice = GetUserChoice(printMenu, 3); switch ( choice ) { case 1: CustomerMenu(); break; case 2: //ManagerMenu(); break; case 3: Console.WriteLine("Thank you for visiting VideoMart at University Boulevard, Goodbye!"); break; default: throw new NotImplementedException(); } }
static void CustomerMenu() { Action printMenu = () => { Console.WriteLine("Press 1 to view movies available to rent."); Console.WriteLine("Press 2 to rent a movie."); Console.WriteLine("Press 3 to view a list of movies you currently have rented."); Console.WriteLine("Press 4 to return a movie rented."); Console.WriteLine("Press 5 to return to main menu."); }; Console.Clear(); Console.WriteLine("-----------------------------------------------------------------------------------------------------------"); // introducing the user with the menu Console.WriteLine("Below is a list of actions that can be performed by customers!"); Console.WriteLine(); printMenu(); Console.WriteLine("-----------------------------------------------------------------------------------------------------------"); Console.WriteLine(); uint choice = GetUserChoice(printMenu, 5); switch ( choice ) { case 1: //MoviesAvailable(); break; case 2: //RentMovie(); break; case 3: //RentedMovies(); break; case 4: //ReturnMovie(); break; case 5: MainMenu(); break; default: throw new NotImplementedException(); } }
使用自动菜单管理器
这是菜单选项类:
public class MenuChoice { public string Title { get; private set; } public Action Action { get; private set; } public MenuChoice(string title, Action action) { Title = title; Action = action; } }
这是菜单类:
public class Menu {
private readonly string Separator = new string('-', 100); private string Header; private List<MenuChoice> Choices; private Menu Root;
public Menu(string header, List<MenuChoice> choices, Menu root) { Header = header; Choices = choices; Root = root; }
private void Print() { for ( int index = 0; index < Choices.Count; index++ ) Console.WriteLine($"Press {index + 1} {Choices[index].Title}"); Console.WriteLine($"Press {Choices.Count + 1} to " + $"{( Root == null ? "exit" : "go to previous menu" )}"); }
public void Run() { Console.Clear(); Console.WriteLine(Separator); Console.WriteLine(Header); Console.WriteLine(); Print(); Console.WriteLine(Separator); uint choice = GetUserChoice(); if ( choice == Choices.Count + 1 ) if ( Root == null ) { Console.WriteLine("Thank you for visiting VideoMart at University Boulevard, Goodbye!"); return; } else Root.Run(); else { var action = Choices[(int)choice - 1].Action; if ( action != null ) action(); else { Console.WriteLine("Not implemented yet, press a key to continue."); Console.ReadKey(); Run(); } } }
uint GetUserChoice() { uint choice = 0; Action getInput = () => { uint.TryParse(Console.ReadLine(), out choice); }; getInput(); while ( choice < 1 || choice > Choices.Count + 1 ) { Console.WriteLine(); Console.WriteLine("Please try again"); Print(); getInput(); } return choice; }
}
这是菜单管理器类:
public class MenuManager { private Menu Root; public MenuManager(Menu root) { Root = root; } public void Run() { Root.Run(); } }
这里是菜单管理器的初始化,在选择中使用方法或另一个菜单而不是空值:
Here the menu manager initialization, using methods or another menu instead of null in choices:
var choicesMain = new List<MenuChoice>(); var choicesCustomer = new List<MenuChoice>(); var choicesManager = new List<MenuChoice>(); string headerMain = "Welcome to VideoMart at University Boulevard!" + Environment.NewLine + "At VideoMart you are able to rent a variety of movies from many genres such as action, family, horror, etc!"; string headerCustomer = "Below is a list of actions that can be performed by customers!"; string headerManager = "Below is a list of actions that can be performed by managers!"; var root = new Menu(headerMain, choicesMain, null); var menuCustomer = new Menu(headerCustomer, choicesCustomer, root); var menuManager = new Menu(headerManager, choicesManager, root); choicesMain.Add(new MenuChoice("if you are a customer", menuCustomer.Run)); choicesMain.Add(new MenuChoice("if you are a manager", menuManager.Run)); choicesCustomer.Add(new MenuChoice("to view movies available to rent.", null)); choicesCustomer.Add(new MenuChoice("to rent a movie.", null)); choicesCustomer.Add(new MenuChoice("to view a list of movies you currently have rented.", null)); choicesCustomer.Add(new MenuChoice("to return a movie rented.", null));
现在要做的是:
new MenuManager(root).Run();