// Map user input (0, 1, 2...) to human-readable action names
// The actions should match up with the menuText string.
private enum MainMenuAction : int
{
invalid = 0,
repeat = 1,
addBook = 1,
deleteBook = 2,
// TODO etc.. fill the rest in
exit = 7,
}
// What we want our main menu to say.
// The numbers should match up with the MainMenuAction enum.
private static readonly string menuText =
"Welcome to Library.\n" +
"What do you want to do?\n" +
"1. Add a book.\n" +
"2. Delete a book.\n" +
"TODO etc... fill it out here\n" +
"7. Exit.";
public void mainMenu(BookList bookList)
{
// Make sure bookList is not null, since we will be operating on it.
if (bookList == null)
{
// TODO Handle null bookList
return;
}
// Do our application-level looping here
do
{
// Display the main menu text
Console.WriteLine(menuText);
// Get the user input
int userChoice;
if (tryGetInput(out userChoice))
{
// If user wants to exit, then exit the main menu.
if (userChoice == (int)MainMenuAction.exit)
{
break;
}
// Handle the user input by casting the int to a human-readable name
handleMainMenuAction((MainMenuAction)userChoice, bookList);
}
else
{
// TODO Handle unexpected input (parsing to int failed, user error)
}
} while (true);
}
private void handleMainMenuAction(MainMenuAction action, BookList bookList)
{
// Make sure bookList is not null, since we will be operating on it.
if (bookList == null)
{
// TODO Handle null bookList
return;
}
// Ensure that the enum is defined
if (!Enum.IsDefined(typeof(MainMenuAction), action))
{
// TODO Handle undefined enum (user error)
return;
}
switch (action)
{
case MainMenuAction.addBook:
// Command-level looping
do
{
bookList.addBook();
} while (askUserForRepeat("Add another book"));
break;
case MainMenuAction.deleteBook:
bookList.deleteBook();
break;
// TODO Fill out the other cases
case MainMenuAction.invalid:
default:
// TODO Handle invalid action (internal error -- not yet implmented, probably)
break;
}
}
// Just a wrapped version of int.TryParse that grabs from the command line
private bool tryGetInput(out int input)
{
return int.TryParse(Console.ReadLine(), out input);
}
// Displays 'repeatText' as the first option, the second option is to go back to the main menu
// Basically a yes/no continue loop where 1 = continue and anything else = quit
private bool askUserForRepeat(string repeatText)
{
Console.WriteLine("1. " + repeatText);
Console.WriteLine("2. Back to Main Menu");
int userInput;
if (tryGetInput(out userInput))
{
if (userInput == (int)MainMenuAction.repeat)
{
return true;
}
else
{
// Go back to main menu -- user ended repeat.
return false;
}
}
else
{
// Go back to main menu -- invalid user input.
return false;
}
}
// Map user input (0, 1, 2...) to human-readable action names
// The actions should match up with the menuText string.
private enum MainMenuAction : int
{
invalid = 0,
repeat = 1,
addBook = 1,
deleteBook = 2,
// etc..
exit = 7,
}
// What we want our main menu to say.
// The numbers should match up with the MainMenuAction enum.
private static readonly string menuText =
"Welcome to Library.\n" +
"What do you want to do?\n" +
"1. Add a book.\n" +
"2. Delete a book.\n" +
"TODO etc... fill it out here\n" +
"7. Exit.";
public void mainMenu(BookList bookList)
{
// Make sure bookList is not null, since we will be operating on it.
if (bookList == null)
{
// TODO Handle null bookList
return;
}
// Do our application-level looping here
do
{
// Display the main menu text
Console.WriteLine(menuText);
// Get the user input
int userChoice;
if (tryGetInput(out userChoice))
{
// If user wants to exit, then exit the main menu.
if (userChoice == (int)MainMenuAction.exit)
{
break;
}
// Handle the user input by casting the int to a human-readable name
handleMainMenuAction((MainMenuAction)userChoice, bookList);
}
else
{
// TODO Handle unexpected input (parsing to int failed, user error)
}
} while (true);
}
private void handleMainMenuAction(MainMenuAction action, BookList bookList)
{
// Make sure bookList is not null, since we will be operating on it.
if (bookList == null)
{
// TODO Handle null bookList
return;
}
// Ensure that the enum is defined
if (!Enum.IsDefined(typeof(MainMenuAction), action))
{
// TODO Handle undefined enum (user error)
return;
}
switch (action)
{
case MainMenuAction.addBook:
// Command-level looping
do
{
bookList.addBook();
} while (askUserForRepeat("Add another book"));
break;
case MainMenuAction.deleteBook:
bookList.deleteBook();
break;
// TODO Fill out the other cases
case MainMenuAction.invalid:
default:
// TODO Handle invalid action (internal error -- not yet implmented, probably)
break;
}
}
// Just a wrapped version of int.TryParse that grabs from the command line
private bool tryGetInput(out int input)
{
return int.TryParse(Console.ReadLine(), out input);
}
// Displays 'repeatText' as the first option, the second option is to go back to the main menu
// Basically a yes/no continue loop where 1 = continue and anything else = quit
private bool askUserForRepeat(string repeatText)
{
Console.WriteLine("1. " + repeatText);
Console.WriteLine("2. Back to Main Menu");
int userInput;
if (tryGetInput(out userInput))
{
if (userInput == (int)MainMenuAction.repeat)
{
return true;
}
else
{
// Go back to main menu -- user ended repeat.
return false;
}
}
else
{
// Go back to main menu -- invalid user input.
return false;
}
}
// Map user input (0, 1, 2...) to human-readable action names
// The actions should match up with the menuText string.
private enum MainMenuAction : int
{
invalid = 0,
repeat = 1,
addBook = 1,
deleteBook = 2,
// TODO etc.. fill the rest in
exit = 7,
}
// What we want our main menu to say.
// The numbers should match up with the MainMenuAction enum.
private static readonly string menuText =
"Welcome to Library.\n" +
"What do you want to do?\n" +
"1. Add a book.\n" +
"2. Delete a book.\n" +
"TODO etc... fill it out here\n" +
"7. Exit.";
public void mainMenu(BookList bookList)
{
// Make sure bookList is not null, since we will be operating on it.
if (bookList == null)
{
// TODO Handle null bookList
return;
}
// Do our application-level looping here
do
{
// Display the main menu text
Console.WriteLine(menuText);
// Get the user input
int userChoice;
if (tryGetInput(out userChoice))
{
// If user wants to exit, then exit the main menu.
if (userChoice == (int)MainMenuAction.exit)
{
break;
}
// Handle the user input by casting the int to a human-readable name
handleMainMenuAction((MainMenuAction)userChoice, bookList);
}
else
{
// TODO Handle unexpected input (parsing to int failed, user error)
}
} while (true);
}
private void handleMainMenuAction(MainMenuAction action, BookList bookList)
{
// Make sure bookList is not null, since we will be operating on it.
if (bookList == null)
{
// TODO Handle null bookList
return;
}
// Ensure that the enum is defined
if (!Enum.IsDefined(typeof(MainMenuAction), action))
{
// TODO Handle undefined enum (user error)
return;
}
switch (action)
{
case MainMenuAction.addBook:
// Command-level looping
do
{
bookList.addBook();
} while (askUserForRepeat("Add another book"));
break;
case MainMenuAction.deleteBook:
bookList.deleteBook();
break;
// TODO Fill out the other cases
case MainMenuAction.invalid:
default:
// TODO Handle invalid action (internal error -- not yet implmented, probably)
break;
}
}
// Just a wrapped version of int.TryParse that grabs from the command line
private bool tryGetInput(out int input)
{
return int.TryParse(Console.ReadLine(), out input);
}
// Displays 'repeatText' as the first option, the second option is to go back to the main menu
// Basically a yes/no continue loop where 1 = continue and anything else = quit
private bool askUserForRepeat(string repeatText)
{
Console.WriteLine("1. " + repeatText);
Console.WriteLine("2. Back to Main Menu");
int userInput;
if (tryGetInput(out userInput))
{
if (userInput == (int)MainMenuAction.repeat)
{
return true;
}
else
{
// Go back to main menu -- user ended repeat.
return false;
}
}
else
{
// Go back to main menu -- invalid user input.
return false;
}
}
Remember to always guard your inputs. We don't know if bookList
is null or not and we are attempting to use it by calling a method on it. This will cause a NullReferenceException. Simply check if it is null before using it.
// Map user input (0, 1, 2...) to human-readable action names
// The actions should match up with the menuText string.
private enum MainMenuAction : int
{
invalid = 0,
repeat = 1,
addBook = 1,
deleteBook = 2,
// etc..
exit = 7,
}
// What we want our main menu to say.
// The numbers should match up with the MainMenuAction enum.
private static readonly string menuText =
"Welcome to Library.\n" +
"What do you want to do?\n" +
"1. Add a book.\n" +
"2. Delete a book.\n" +
"TODO etc... fill it out here\n" +
"7. Exit.";
public void mainMenu(BookList bookList)
{
// Make sure bookList is not null, since we will be operating on it.
if (bookList == null)
{
// TODO Handle null bookList
return;
}
// Do our application-level looping here
do
{
// Display the main menu text
Console.WriteLine(menuText);
// Get the user input
int userChoice;
if (tryGetInput(out userChoice))
{
// If user wants to exit, then exit the main menu.
if (userChoice == (int)MainMenuAction.exit)
{
break;
}
// Handle the user input by casting the int to a human-readable name
handleMainMenuAction((MainMenuAction)userChoice, bookList);
}
else
{
// TODO Handle unexpected input (parsing to int failed, user error)
}
} while (true);
}
private void handleMainMenuAction(MainMenuAction action, BookList bookList)
{
// Make sure bookList is not null, since we will be operating on it.
if (bookList == null)
{
// TODO Handle null bookList
return;
}
// Ensure that the enum is defined
if (!Enum.IsDefined(typeof(MainMenuAction), action))
{
// TODO Handle undefined enum (user error)
return;
}
switch (action)
{
case MainMenuAction.addBook:
// Command-level looping
do
{
bookList.addBook();
} while (askUserForRepeat("Add another book"));
break;
case MainMenuAction.deleteBook:
bookList.deleteBook();
break;
// TODO Fill out the other cases
case MainMenuAction.invalid:
default:
// TODO Handle invalid action (internal error -- not yet implmented, probably)
break;
}
}
// Just a wrapped version of int.TryParse that grabs from the command line
private bool tryGetInput(out int input)
{
return int.TryParse(Console.ReadLine(), out input);
}
// Displays 'repeatText' as the first option, the second option is to go back to the main menu
// Basically a yes/no continue loop where 1 = continue and anything else = quit
private bool askUserForRepeat(string repeatText)
{
Console.WriteLine("1. " + repeatText);
Console.WriteLine("2. Back to Main Menu");
int userInput;
if (tryGetInput(out userInput))
{
if (userInput == (int)MainMenuAction.repeat)
{
return true;
}
else
{
// Go back to main menu -- user ended repeat.
return false;
}
}
else
{
// Go back to main menu -- invalid user input.
return false;
}
}
// Map user input (0, 1, 2...) to human-readable action names
// The actions should match up with the menuText string.
private enum MainMenuAction : int
{
invalid = 0,
repeat = 1,
addBook = 1,
deleteBook = 2,
// etc..
exit = 7,
}
// What we want our main menu to say.
// The numbers should match up with the MainMenuAction enum.
private static readonly string menuText =
"Welcome to Library.\n" +
"What do you want to do?\n" +
"1. Add a book.\n" +
"2. Delete a book.\n" +
"TODO etc... fill it out here\n" +
"7. Exit.";
public void mainMenu(BookList bookList)
{
// Do our application-level looping here
do
{
// Display the main menu text
Console.WriteLine(menuText);
// Get the user input
int userChoice;
if (tryGetInput(out userChoice))
{
// If user wants to exit, then exit the main menu.
if (userChoice == (int)MainMenuAction.exit)
{
break;
}
// Handle the user input by casting the int to a human-readable name
handleMainMenuAction((MainMenuAction)userChoice, bookList);
}
else
{
// TODO Handle unexpected input (parsing to int failed, user error)
}
} while (true);
}
private void handleMainMenuAction(MainMenuAction action, BookList bookList)
{
// Ensure that the enum is defined
if (!Enum.IsDefined(typeof(MainMenuAction), action))
{
// TODO Handle undefined enum (user error)
return;
}
switch (action)
{
case MainMenuAction.addBook:
// Command-level looping
do
{
bookList.addBook();
} while (askUserForRepeat("Add another book"));
break;
case MainMenuAction.deleteBook:
bookList.deleteBook();
break;
// TODO Fill out the other cases
case MainMenuAction.invalid:
default:
// TODO Handle invalid action (internal error -- not yet implmented, probably)
break;
}
}
// Just a wrapped version of int.TryParse that grabs from the command line
private bool tryGetInput(out int input)
{
return int.TryParse(Console.ReadLine(), out input);
}
// Displays 'repeatText' as the first option, the second option is to go back to the main menu
// Basically a yes/no continue loop where 1 = continue and anything else = quit
private bool askUserForRepeat(string repeatText)
{
Console.WriteLine("1. " + repeatText);
Console.WriteLine("2. Back to Main Menu");
int userInput;
if (tryGetInput(out userInput))
{
if (userInput == (int)MainMenuAction.repeat)
{
return true;
}
else
{
// Go back to main menu -- user ended repeat.
return false;
}
}
else
{
// Go back to main menu -- invalid user input.
return false;
}
}
Remember to always guard your inputs. We don't know if bookList
is null or not and we are attempting to use it by calling a method on it. This will cause a NullReferenceException. Simply check if it is null before using it.
// Map user input (0, 1, 2...) to human-readable action names
// The actions should match up with the menuText string.
private enum MainMenuAction : int
{
invalid = 0,
repeat = 1,
addBook = 1,
deleteBook = 2,
// etc..
exit = 7,
}
// What we want our main menu to say.
// The numbers should match up with the MainMenuAction enum.
private static readonly string menuText =
"Welcome to Library.\n" +
"What do you want to do?\n" +
"1. Add a book.\n" +
"2. Delete a book.\n" +
"TODO etc... fill it out here\n" +
"7. Exit.";
public void mainMenu(BookList bookList)
{
// Make sure bookList is not null, since we will be operating on it.
if (bookList == null)
{
// TODO Handle null bookList
return;
}
// Do our application-level looping here
do
{
// Display the main menu text
Console.WriteLine(menuText);
// Get the user input
int userChoice;
if (tryGetInput(out userChoice))
{
// If user wants to exit, then exit the main menu.
if (userChoice == (int)MainMenuAction.exit)
{
break;
}
// Handle the user input by casting the int to a human-readable name
handleMainMenuAction((MainMenuAction)userChoice, bookList);
}
else
{
// TODO Handle unexpected input (parsing to int failed, user error)
}
} while (true);
}
private void handleMainMenuAction(MainMenuAction action, BookList bookList)
{
// Make sure bookList is not null, since we will be operating on it.
if (bookList == null)
{
// TODO Handle null bookList
return;
}
// Ensure that the enum is defined
if (!Enum.IsDefined(typeof(MainMenuAction), action))
{
// TODO Handle undefined enum (user error)
return;
}
switch (action)
{
case MainMenuAction.addBook:
// Command-level looping
do
{
bookList.addBook();
} while (askUserForRepeat("Add another book"));
break;
case MainMenuAction.deleteBook:
bookList.deleteBook();
break;
// TODO Fill out the other cases
case MainMenuAction.invalid:
default:
// TODO Handle invalid action (internal error -- not yet implmented, probably)
break;
}
}
// Just a wrapped version of int.TryParse that grabs from the command line
private bool tryGetInput(out int input)
{
return int.TryParse(Console.ReadLine(), out input);
}
// Displays 'repeatText' as the first option, the second option is to go back to the main menu
// Basically a yes/no continue loop where 1 = continue and anything else = quit
private bool askUserForRepeat(string repeatText)
{
Console.WriteLine("1. " + repeatText);
Console.WriteLine("2. Back to Main Menu");
int userInput;
if (tryGetInput(out userInput))
{
if (userInput == (int)MainMenuAction.repeat)
{
return true;
}
else
{
// Go back to main menu -- user ended repeat.
return false;
}
}
else
{
// Go back to main menu -- invalid user input.
return false;
}
}
Starting with a small nitpick, that the rest of the application code already has -- use full names for variables. Avoid the habit of short variable names like b
. Feel free to use the full name of boardList
instead. Remember that readability, clarity, and simplicity are key in programming.
The next issue with the code is the line this.mainMenu(b);
. This causes a recursive call that can fill the stack if called many many times (via the input "1" -> "any key but 1" -> repeat) or worse, cause some interesting bugs later on.
Try adding another console output after this.mainMenu(b);
, hit the above path a couple of times, and try to figure out what happens.
// Map user input (0, 1, 2...) to human-readable action names
// The actions should match up with the menuText string.
private enum MainMenuAction : int
{
invalid = 0,
repeat = 1,
addBook = 1,
deleteBook = 2,
// etc..
exit = 7,
}
// What we want our main menu to say.
// The numbers should match up with the MainMenuAction enum.
private static readonly string menuText =
"Welcome to Library.\n" +
"What do you want to do?\n" +
"1. Add a book.\n" +
"2. Delete a book.\n" +
"TODO etc... fill it out here\n" +
"7. Exit.";
public void mainMenu(BookList bookList)
{
// Do our application-level looping here
do
{
// Display the main menu text
Console.WriteLine(menuText);
// Get the user input
int userChoice;
if (tryGetInput(out userChoice))
{
// If user wants to exit, then exit the main menu.
if (userChoice == (int)MainMenuAction.exit)
{
break;
}
// Handle the user input by casting the int to a human-readable name
handleMainMenuAction((MainMenuAction)userChoice, bookList);
}
else
{
// TODO Handle unexpected input (parsing to int failed, user error)
}
} while (true);
}
private void handleMainMenuAction(MainMenuAction action, BookList bookList)
{
// Ensure that the enum is defined
if (!Enum.IsDefined(typeof(MainMenuAction), action))
{
// TODO Handle undefined enum (user error)
return;
}
switch (action)
{
case MainMenuAction.addBook:
// Command-level looping
do
{
bookList.addBook();
} while (askUserForRepeat("Add another book"));
break;
case MainMenuAction.deleteBook:
bookList.deleteBook();
break;
// TODO Fill out the other cases
case MainMenuAction.invalid:
default:
// TODO Handle invalid action (internal error -- not yet implmented, probably)
break;
}
}
// Just a wrapped version of int.TryParse that grabs from the command line
private bool tryGetInput(out int input)
{
return int.TryParse(Console.ReadLine(), out input);
}
// Displays 'repeatText' as the first option, the second option is to go back to the main menu
// Basically a yes/no continue loop where 1 = continue and anything else = quit
private bool askUserForRepeat(string repeatText)
{
Console.WriteLine("1. " + repeatText);
Console.WriteLine("2. Back to Main Menu");
int userInput;
if (tryGetInput(out userInput))
{
if (userInput == (int)MainMenuAction.repeat)
{
return true;
}
else
{
// Go back to main menu -- user ended repeat.
return false;
}
}
else
{
// Go back to main menu -- invalid user input.
return false;
}
}
The next issue with the code is the line this.mainMenu(b);
. This causes a recursive call that can fill the stack if called many many times (via the input "1" -> "any key but 1" -> repeat).
// Map user input (0, 1, 2...) to human-readable action names
// The actions should match up with the menuText string.
private enum MainMenuAction : int
{
invalid = 0,
repeat = 1,
addBook = 1,
deleteBook = 2,
// etc..
exit = 7,
}
// What we want our main menu to say.
// The numbers should match up with the MainMenuAction enum.
private static readonly string menuText =
"Welcome to Library.\n" +
"What do you want to do?\n" +
"1. Add a book.\n" +
"2. Delete a book.\n" +
"TODO etc... fill it out here\n" +
"7. Exit.";
public void mainMenu(BookList bookList)
{
// Do our application-level looping here
do
{
// Display the main menu text
Console.WriteLine(menuText);
// Get the user input
int userChoice;
if (tryGetInput(out userChoice))
{
// If user wants to exit, then exit the main menu.
if (userChoice == (int)MainMenuAction.exit)
{
break;
}
// Handle the user input by casting the int to a human-readable name
handleMainMenuAction((MainMenuAction)userChoice, bookList);
}
else
{
// TODO Handle unexpected input (parsing to int failed, user error)
}
} while (true);
}
private void handleMainMenuAction(MainMenuAction action, BookList bookList)
{
// Ensure that the enum is defined
if (!Enum.IsDefined(typeof(MainMenuAction), action))
{
// TODO Handle undefined enum (user error)
return;
}
switch (action)
{
case MainMenuAction.addBook:
// Command-level looping
do
{
bookList.addBook();
} while (askUserForRepeat("Add another book"));
break;
case MainMenuAction.deleteBook:
bookList.deleteBook();
break;
case MainMenuAction.invalid:
default:
// TODO Handle invalid action (internal error -- not yet implmented, probably)
break;
}
}
// Just a wrapped version of int.TryParse that grabs from the command line
private bool tryGetInput(out int input)
{
return int.TryParse(Console.ReadLine(), out input);
}
// Displays 'repeatText' as the first option, the second option is to go back to the main menu
// Basically a yes/no continue loop where 1 = continue and anything else = quit
private bool askUserForRepeat(string repeatText)
{
Console.WriteLine("1. " + repeatText);
Console.WriteLine("2. Back to Main Menu");
int userInput;
if (tryGetInput(out userInput))
{
if (userInput == (int)MainMenuAction.repeat)
{
return true;
}
else
{
// Go back to main menu -- user ended repeat.
return false;
}
}
else
{
// Go back to main menu -- invalid user input.
return false;
}
}
Starting with a small nitpick, that the rest of the application code already has -- use full names for variables. Avoid the habit of short variable names like b
. Feel free to use the full name of boardList
instead. Remember that readability, clarity, and simplicity are key in programming.
The next issue with the code is the line this.mainMenu(b);
. This causes a recursive call that can fill the stack if called many many times (via the input "1" -> "any key but 1" -> repeat) or worse, cause some interesting bugs later on.
Try adding another console output after this.mainMenu(b);
, hit the above path a couple of times, and try to figure out what happens.
// Map user input (0, 1, 2...) to human-readable action names
// The actions should match up with the menuText string.
private enum MainMenuAction : int
{
invalid = 0,
repeat = 1,
addBook = 1,
deleteBook = 2,
// etc..
exit = 7,
}
// What we want our main menu to say.
// The numbers should match up with the MainMenuAction enum.
private static readonly string menuText =
"Welcome to Library.\n" +
"What do you want to do?\n" +
"1. Add a book.\n" +
"2. Delete a book.\n" +
"TODO etc... fill it out here\n" +
"7. Exit.";
public void mainMenu(BookList bookList)
{
// Do our application-level looping here
do
{
// Display the main menu text
Console.WriteLine(menuText);
// Get the user input
int userChoice;
if (tryGetInput(out userChoice))
{
// If user wants to exit, then exit the main menu.
if (userChoice == (int)MainMenuAction.exit)
{
break;
}
// Handle the user input by casting the int to a human-readable name
handleMainMenuAction((MainMenuAction)userChoice, bookList);
}
else
{
// TODO Handle unexpected input (parsing to int failed, user error)
}
} while (true);
}
private void handleMainMenuAction(MainMenuAction action, BookList bookList)
{
// Ensure that the enum is defined
if (!Enum.IsDefined(typeof(MainMenuAction), action))
{
// TODO Handle undefined enum (user error)
return;
}
switch (action)
{
case MainMenuAction.addBook:
// Command-level looping
do
{
bookList.addBook();
} while (askUserForRepeat("Add another book"));
break;
case MainMenuAction.deleteBook:
bookList.deleteBook();
break;
// TODO Fill out the other cases
case MainMenuAction.invalid:
default:
// TODO Handle invalid action (internal error -- not yet implmented, probably)
break;
}
}
// Just a wrapped version of int.TryParse that grabs from the command line
private bool tryGetInput(out int input)
{
return int.TryParse(Console.ReadLine(), out input);
}
// Displays 'repeatText' as the first option, the second option is to go back to the main menu
// Basically a yes/no continue loop where 1 = continue and anything else = quit
private bool askUserForRepeat(string repeatText)
{
Console.WriteLine("1. " + repeatText);
Console.WriteLine("2. Back to Main Menu");
int userInput;
if (tryGetInput(out userInput))
{
if (userInput == (int)MainMenuAction.repeat)
{
return true;
}
else
{
// Go back to main menu -- user ended repeat.
return false;
}
}
else
{
// Go back to main menu -- invalid user input.
return false;
}
}