I have a library class that has a Serve() method. What it does is dequeue a person from a queue and Pop a book from a stack. A Book is associated to a Borrower when it is borrowed, that way the method ReturnBook() can accept a string value that corresponds to the name of the person who borrowed the book.
How can I create an association between the Book and the Borrower? It's my first time encountering associations in C#. Here is a sample input and output
INPUT
Lineup("Joker")
Add("Shelter", "Yung Jun", "9781250075611")
Add("The Paper Menagerie and Other Stories", "Liu, Ken", "9781481442541")
Serve()
Joker lined up.
Added Shelter (Yung Jun) to the stack.
Added The Paper Menagerie and Other Stories (Liu, Ken) to the stack.
Joker borrowed Shelter (Yung Jun)
One way to do this is to create a property of one item that is of the type of the other item. For example, a Borrower may have a Book property. Then, when the borrower borrows a book, you just set the value of the Book property to the book they just borrowed.
Following is an illustrative example of how this might work:
To start with, you should create some classes to represent the objects. Here's an example:
class Reader
{
public string Name { get; set; }
public Book BorrowedBook { get; set; }
}
class Book
{
public string Title { get; set; }
public string Author { get; set; }
public string ISBN { get; set; }
}
And it looks like you have a Queue of Readers (called borrowers) and a Stack of Books. I also created a Queue of Readers called returners, which will represent the people who want to return a book:
class Program
{
private static Queue<Reader> borrowers = new Queue<Reader>();
private static Queue<Reader> returners = new Queue<Reader>();
private static Stack<Book> books = new Stack<Book>();
Now, it looks like you have some helper methods that will add a reader to the queue or a book to the stack. Since I can see that these may need to be used to add new items OR existing items (like when a reader returns a book, the existing book will get added back to the library), I create two versions of them - one with no arguments (which will then get the details of the object from the user), and one with an argument (which will add that object to the queue or stack):
private static void Lineup()
{
var newReader = new Reader();
Console.Write("Enter the name of the new reader: ");
newReader.Name = Console.ReadLine();
// Now that we have a reader object, call the
// other version of this method to add it
Lineup(newReader);
}
private static void Lineup(Reader borrower)
{
borrowers.Enqueue(borrower);
Console.WriteLine($"{borrower.Name} lined up to borrow a book.");
}
private static void Add()
{
var newBook = new Book();
Console.Write("Enter the book title: ");
newBook.Title = Console.ReadLine();
Console.Write("Enter the book author: ");
newBook.Author = Console.ReadLine();
Console.Write("Enter the book ISBN: ");
newBook.ISBN = Console.ReadLine();
// Now that we have a book object, call the
// other version of this method to add it
Add(newBook);
}
private static void Add(Book book)
{
books.Push(book);
Console.WriteLine($"Added '{book.Title}' to the library.");
}
Finally, we need some methods to service our borrowers (Dequeue a borrower and Pop a book, then give the book to the borrower) and our returners (Push the book back to the library, and, if the person wants to borrow another one, Enqueue them back in the borrowers line):
private static void ServiceBorrower()
{
if (borrowers.Count == 0)
{
Console.WriteLine($"There are no more borrowers waiting in line.");
}
else if (books.Count == 0)
{
Console.WriteLine($"There are no more books to loan.");
if (returners.Count > 0)
{
Console.WriteLine(" - Hint: There are people waiting to return books.");
}
}
else
{
var borrower = borrowers.Dequeue();
var book = books.Pop();
borrower.BorrowedBook = book;
Console.WriteLine($"{borrower.Name} borrowed {book.Title}");
returners.Enqueue(borrower);
}
}
private static void ServiceReturner()
{
if (returners.Count == 0)
{
Console.WriteLine($"There are no more returners waiting in line.");
}
else
{
var returner = returners.Dequeue();
var book = returner.BorrowedBook;
returner.BorrowedBook = null;
Add(book);
Console.WriteLine($"{returner.Name} has returned {book.Title}.");
Console.Write("Do they want to borrow another one (Y/N)?: ");
var input = Console.ReadKey();
Console.WriteLine();
if (input.Key == ConsoleKey.Y)
{
Lineup(returner);
}
}
}
Now, we just need to give our user some options as to what they want the program to do, and continue looping on their input until they decide to quit:
static void Main()
{
bool exit = false;
Console.WriteLine("Please choose an option:");
Console.WriteLine("1. Enter a new reader");
Console.WriteLine("2. Enter a new book");
Console.WriteLine("3. Service the next borrower");
Console.WriteLine("4. Service the next returner");
Console.WriteLine("5. Exit the program");
while (!exit)
{
Console.Write("\nEnter choice (1-5): ");
int input;
while (!int.TryParse(Console.ReadLine(), out input) || input < 1 || input > 5)
{
Console.Write("Invalid input. Enter a number from 1-5: ");
}
switch(input)
{
case 1:
Lineup();
break;
case 2:
Add();
break;
case 3:
ServiceBorrower();
break;
case 4:
ServiceReturner();
break;
case 5:
exit = true;
break;
}
}
Console.Write("\nDone!\nPress any key to exit...");
Console.ReadKey();
}
Output:
Related
I need to find a node with input from a customer in the linked list but I have an error CS1503. How can I solve a problem?
In this code, I create the LinkList name "customerList" to collect string data such as name, contact number, and payment from the user. After that, I need to find the contact number which input from the user to show data in the node and delete it. In code show that input in "searchCustomerDetail" cannot convert 'string' to ....
Error Message: Argument 1: cannot convert from 'string' to 'IFN564.Customer' [IFN564]csharp(CS1503)
public class Customer {
public string Name { get; set; }
public string Phone { get; set; }
public string Payment { get; set; }
public int[] Screening { get; set; }
public static LinkedList<Customer> customerList = new LinkedList<Customer>();
public static string input;
public static void addCustomerDetail() {
Console.WriteLine("Please enter your information detail");
Console.WriteLine("");
Console.Write("Full Name: ");
string inputName = Console.ReadLine();
Console.Write("Contact Number: ");
string inputPhone = Console.ReadLine();
Console.Write("Payment Method: ");
string inputPayment = Console.ReadLine();
Console.Clear();
Console.WriteLine("");
Console.WriteLine("Please check your information detail!!");
Console.WriteLine("");
Console.WriteLine($"Full Name: {inputName}");
Console.WriteLine($"Contact Number: {inputPhone}");
Console.WriteLine($"Payment Method: {inputPayment}");
Console.WriteLine("");
Console.WriteLine("Please 1 to confirm or 0 to cancel");
int input = Convert.ToInt32(Console.ReadLine());
switch (input) {
case 1:
insert(inputName, inputPhone, inputPayment);
break;
case 2:
Program.Main();
break;
}
}
public static void insert(string name, string phone, string payment) {
Console.WriteLine("");
Console.WriteLine("Please 1 to confirm buy ticket or 0 to cancel");
int input = Convert.ToInt32(Console.ReadLine());
Customer customerDetail = new Customer() {
Name = name,
Phone = phone,
Payment = payment,
};
switch (input) {
case 0: Program.Main(); break;
case 1:
customerList.AddLast(customerDetail);
Program.Main();
break;
}
}
public static void searchCunstomerDetail() {
Console.WriteLine("Please enter contact number!!");
Console.WriteLine("");
Console.Write("Contact number: ");
input = Console.ReadLine();
LinkedListNode<Customer> node = customerList.Find(input);
Console.WriteLine(node);
}
}
I try to use LinkListNode to find but It show error with input CS1503
you need to use LINQ where
var node = customerList.Where(c=>c.Phone == input).First();
The error is with this statement:
LinkedListNode<Customer> node = customerList.Find(input);
customerList.Find searches the customerList for an element (in this case, a Customer) that equals the argument provided to Find (in this case, the var, input). input is a string, not Customer, so it can't be used in Find here.
What you seemingly intend to do here is to find the Customer in customerList that has a Customer.Phone that equals the input string. To do so, you can use LINQ, as others have suggested:
LinkedListNode<Customer> node = customerList.FirstOrDefault(c => c.Phone == input);
The above expression will find the first element in the list that returns true for the provided function (predicate), and will return null if none match.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
I am making a console application and I have a "Menu" where the user can enter information to create a new Person object. The following is inside a method.
Write("Please enter the first name: ", false);
string fName = Console.ReadLine().ToUpper();
Write("Please enter the middle initial: ", false);
string mInitial = Console.ReadLine().ToUpper();
Write("Please enter the last name: ", false);
string lName = Console.ReadLine().ToUpper();
like so. I want the user to be able to exit the method at anytime if they decide they don't want to be making a new person. So I'd like to make a new method called "CheckExit" and if they type "EXIT" it will leave the "CreatePerson" method. So I want the "CheckExit" to return a return. Otherwise I have to add an "if" statement after every input and that gets clutter-y.
Is this possible? Does return have a return type? What would be the proper way to do this?
return is not a type that you can return, it's a keyword for returning a result. So unfortunately what you are trying to do is not possible.
However, you can make your code much more readable and extendable by using an array of queries and getting the results for each inside of a loop. This has the bonus effect of being able to add more queries with ease.
// you can put these queries somewhere outside the function
string[] queries = {"Please enter the first name: ", ...}
var results = new List<string>();
foreach (string query in queries) {
Write(query, false);
var result = Console.ReadLine().ToUpper();
if (result.Equals("EXIT") {
return;
}
results.Add(result);
}
// handle your inputs from the results list here ...
You could create a method to read from console to automate this process, something like
internal class StopCreatingPersonException : Exception
{}
public static string ReadFromConsole(string prompt)
{
Write(prompt, false);
var v = Console.ReadLine().ToUpper();
if (v == "EXIT") { throw new StopCreatingPerson (); }
return v;
}
Then your code would look like:
try {
string fName = ReadFromConsole("Please enter the first name: ");
....
}
catch (StopCreatingPersonException)
{ }
Return statements are used to return a value from a method that has a return type. When you write a method with void as the return type, you can use the return; to exit the method.
e.g, following method uses a string as the return type,
public string ReturnString() { return "thisString"; }
If you are writing a method that creates the object and returns it to the calling method, then the return type would be the Person (unless you intend do something else). If you check the user input and decide not to create a Person, you can use return null;.
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Initial { get; set; }
}
public static Person CreatePerson()
{
Person person = new Person();
Console.Write("Please enter the first name: ", false);
string fName = Console.ReadLine().ToUpper();
if (string.IsNullOrEmpty(fName) || fName.ToLower().Equals("exit"))
return null;
person.FirstName = fName;
Console.Write("Please enter the middle initial: ", false);
string mInitial = Console.ReadLine().ToUpper();
if (string.IsNullOrEmpty(mInitial) || mInitial.ToLower().Equals("exit"))
return null;
person.Initial = mInitial;
Console.Write("Please enter the last name: ", false);
string lName = Console.ReadLine().ToUpper();
if (string.IsNullOrEmpty(lName) || lName.ToLower().Equals("exit"))
return null;
person.LastName = lName;
return person;
}
And you can use this method in the Main,
public static void Main(string[] args)
{
Person person = CreatePerson();
if (person == null) {
Console.WriteLine("User Exited.");
}
else
{
// Do Something with person.
}
}
The only way is to use return if you want to terminate method. But you can shorten your code some thing like this:
static void Main(string[] args)
{
createPerson();
Console.WriteLine("Some display goes here...");
}
static void createPerson()
{
Console.WriteLine("Please enter the first name: ");
string fName = getInput();
if (isExit(fName))
{
return;
}
Console.WriteLine("Please enter the middle initial: ");
string mInitial = getInput();
if (isExit(mInitial))
{
return;
}
Console.WriteLine("Please enter the last name: ");
string lName = getInput();
if (isExit(lName))
{
return;
}
}
static string getInput()
{
return Console.ReadLine().ToUpper();
}
static bool isExit(string value)
{
if (value == "EXIT")
{
Console.WriteLine("Create person has been canceled by the user.");
return true;
}
return false;
}
I'm trying to create menu for my simple app. I want to use switch but I can't find a way to call functions in uninstanced class which is instanced on application startup.
class Window
{
public void startLibrary(int sizeX, int sizeY)
{
BookList MainLibrary = new BookList();
this.mainMenu();
}
public void mainMenu()
{
string userChoice = Console.ReadLine();
switch (userChoice)
{
case "1":
break;
How do I call MainLibrary's function in case 1. It's obviously not instanced here but I can't find a way pass reference to uninstanced object.
BookList code :
class BookList
{
List<Book> books = new List<Book>();
public void addBook() // adding book
{
string name = Console.ReadLine();
string author = Console.ReadLine();
int relDate = int.Parse(Console.ReadLine());
int uID = books.Count() + 1;
books.Add(new Book(name, author, relDate, uID));
}
public void deleteBook() // deleting book
{
int readForDelete = int.Parse(Console.ReadLine());
books.RemoveAll(Book => Book.UniqueID == readForDelete);
}
public void borrowBook() // borrowing book
{
int readForBorrow = int.Parse(Console.ReadLine());
foreach (Book Book in books)
{
if (Book.UniqueID == readForBorrow)
Book.available = false;
}
}
public void returnBook() // returning book
{
int readForReturn = int.Parse(Console.ReadLine());
foreach (Book Book in books)
{
if (Book.UniqueID == readForReturn)
Book.available = true;
}
}
public void displayBooks() // displaying list of books
{
string isAvailable;
foreach (Book Book in books)
{
if (Book.available == true)
isAvailable = "available";
else
isAvailable = "unavailable";
Console.WriteLine(" {0} {1} {2} {3} {4} ", Book.UniqueID, Book.BookName, Book.BookName, Book.ReleaseDate, isAvailable);
}
}
public string Name
{
get; set;
}
}
}
You either need to pass your BookList instance to your mainMenu() method, or set a global variable. I'd recommend the former.
public void mainMenu(BookList list) { ... }
Then call it like this from startLibrary:
this.mainMenu(MainLibrary);
As a side note, you really need to brush up on your variable, class, and method naming conventions.
You could implement it with lambdas like this:
class Window
{
public void startLibrary(int sizeX, int sizeY)
{
BookList MainLibrary = new BookList();
Action<BookList> action = this.mainMenu();
if (action != null)
{
action(MainLibrary);
}
}
public Action<BookList> mainMenu()
{
string userChoice = Console.ReadLine();
switch (userChoice)
{
case "1":
return b => b.addBook();
}
Or you could just pass a reference to your MainLibrary variable to the method:
class Window
{
public void startLibrary(int sizeX, int sizeY)
{
BookList MainLibrary = new BookList();
this.mainMenu(MainLibrary);
}
public Action<BookList> mainMenu(BookList b)
{
string userChoice = Console.ReadLine();
switch (userChoice)
{
case "1":
b.addBook();
break;
}
First of all, what you've got in your startLibrary method is a local variable - which is accessible only within the block it's defined in. That said, the MainLibrary is not something you can reference from anywhere else.
To solve your problem you have several options.
You can make the MainLibrary a field/member of the Window class. Then all the instance methods of the Window class will have access to it - so as the MainMenu method:
class Window
{
private BookList MainLibrary;
public void startLibrary(int sizeX, int sizeY)
{
this.MainLibrary = new BookList();
this.mainMenu();
}
public void mainMenu()
{
string userChoice = Console.ReadLine();
switch (userChoice)
{
case "1":
// do whatever you want with this.MainLibrary here
break;
/// ...
}
}
}
The other option would be to pass in the MainLIbrary instance you've created into the mainMenu method. Here you'll need to update the signature of the method as follows:
public void mainMenu(BookList list)
{
// reference the list now as necessary
}
I am working on a small C# program that will store student records in a list. I need to use a class to hold each student record, which is the top class in my code sample below.
If the user chooses to create a new record, I place their input into a studentRecord variable and then add it to the recordList. However, when I attempt to display the number of student records currently available using Count(), the program does nothing except re-display the menu, as if totally ignoring my command to display. I think something is wrong with how/where I declared the list, or with how I create a new StudentRecord object each time the menu is run.
Also, all three methods must stay in the first class. Is there any way to fix this?
public class StudentRecord
{
//Declare the various fields of the class
private string strFirstName;
private string strLastName;
private int intCourses;
private int intCreditHours;
List<StudentRecord> lstRecords = new List<StudentRecord>();
//Declare the properties of the class, since the fields are private
public string StrFirstName
{
get
{
return strFirstName;
}
set
{
strFirstName = value;
}
}
public string StrLastName
{
get
{
return strLastName;
}
set
{
strLastName = value;
}
}
public int IntCourses
{
get
{
return intCourses;
}
set
{
intCourses = value;
}
}
public int IntCreditHours
{
get
{
return intCreditHours;
}
set
{
intCreditHours = value;
}
}
//Declare a default constructor
public StudentRecord()
{
}
//Declare a constructor that takes the four necessary parameters, and set the class
// properties equal to the respective parameters
public StudentRecord(string firstName, string lastName, int courses, int creditHours)
{
strFirstName = firstName;
strLastName = lastName;
intCourses = courses;
intCreditHours = creditHours;
}
//Declare a method to perform the adding a student record function
public void mtdAddStudentRecord()
{
//These variables temporarily hold the various user inputs
string strInputFirstName;
string strInputLastName;
int intInputCourses;
int intInputCreditHours;
//Prompt the user to enter the student's first name
Console.Write("Please enter the first name: ");
strInputFirstName = Console.ReadLine();
//Prompt the user to enter the student's last name
Console.Write("Please enter the last name: ");
strInputLastName = Console.ReadLine();
//Prompt the user to enter the student's number of courses
Console.Write("Please enter the number of courses: ");
intInputCourses = int.Parse(Console.ReadLine());
//Prompt the user to enter the student's completed credit hours
Console.Write("Please enter the number of completed credit hours: ");
intInputCreditHours = int.Parse(Console.ReadLine());
//Add the new student record to the list, using the paramaters of the second
// class constructor
lstRecords.Add(new StudentRecord(strInputFirstName, strInputLastName,
intInputCourses, intInputCreditHours));
}
//Declare a method to perform the display student information option
public void mtdDisplayStudentInformation()
{
Console.WriteLine("Capacity: {0}", lstRecords.Count);
}
//Declare a method to perform the edit student information option
public void mtdEditStudentInformation()
{
//TODO
}
}
public class Program
{
public static void Main(string[] args)
{
//Declare and initialize a variable to store the user menu choice
string strMenuChoice;
strMenuChoice = "";
//Perform the necessary menu option while the user has NOT chosen to exit
do
{
//Call the reset method to clear the screen and display the header
mtdResetConsole();
//Display a menu to the user
Console.Write("Please choose an option to perform:" +
"\n - A) Display a list of existing students" +
"\n - B) Add a new student record" +
"\n - C) Edit an existing student record" +
"\n - D) Exit the program" + "\n\n" + " ");
//Store the user reply
strMenuChoice = Console.ReadLine().ToLower();
//Create a new StudentRecord object, and use it to call the various methods
// as chosen by the user
StudentRecord studentRecord = new StudentRecord();
//Determine which option was chosen, and take the appropriate action
switch (strMenuChoice)
{
case "a":
//TODO - Necessary code for option A
mtdResetConsole();
//Perform the "view student records" method
studentRecord.mtdDisplayStudentInformation();
break;
case "b":
//TODO - Necessary code for option B
mtdResetConsole();
//Perform the "add student record" method
studentRecord.mtdAddStudentRecord();
break;
case "c":
//TODO - Necessary code for option C
break;
case "d":
//Exit the program
Environment.Exit(0);
break;
default:
mtdResetConsole();
Console.WriteLine("Error" + "\n" +
" - Please choose a valid option from the list");
//Pause the code from executing for 2.5 seconds, so that the error
// message will be displayed
System.Threading.Thread.Sleep(2500);
break;
}
}
while (strMenuChoice.ToLower() != "d");
}
//Declare a method to reset the console with a blank screen and header
public static void mtdResetConsole()
{
Console.Clear();
Console.WriteLine("CONESTOGA STUDENT RECORDS" + "\n");
}
}
First, put this outside do while
StudentRecord studentRecord = new StudentRecord();
Putting this inside do while means that the object will reset in every loop.
2nd, try to put something like Console.ReadLine() on mtdDisplayStudentInformation method to hold the screen.
public void mtdDisplayStudentInformation()
{
Console.WriteLine("Capacity: {0}", lstRecords.Count);
Console.ReadLine();
}
Kendall, try to separate the logic of your "Records" and your "List of records".
In the case bellow, you have a "list of records" for each record you create.
Suggestions are you create a static variable to make sure it is always the same list on all "Records" or you separate as bellow:
public class StudentRecord
{
//Declare the various fields of the class
private string strFirstName;
private string strLastName;
private int intCourses;
private int intCreditHours;
...
}
public class Program
{
private List<StudentRecord> records = new List<StudentRecord>();
public static void Main(string[] args)
{
...
}
}
Coming from a procedural background, I'm running into a conceptual block while designing a menu-based console application and user input validation. My goal is to display a menu that launches other processes. I want to limit user input to 1, 2, or 3 at the menu.
In a procedural language, I would do something like this pseudocode:
10 print "Make a choice"
20 choice = [dataFromKeyboard]
30 if choice < 4 && choice > 0
40 then 10
50 else 60
60 process valid choices
and no matter what I try, I can't get that out of my head while designing an OO program. Consider (simplified to include only 3 menu items):
class Menu
{
public static void Main(String[] args)
{
DisplayMenu thisdm = new DisplayMenu;
int menuChoice = thisdm.displayMenu();
ProcessMenu thispm = new ProcessMenu();
thispm.processMenu(menuChoice);
}
}
class DisplayMenu
{
public int displayMenu()
{
Console.WriteLine("1 - foo3");
Console.WriteLine("2 - foo2");
Console.WriteLine("3 - foo3");
Console.WriteLine("choose");
String choice = Console.ReadLine();
int intChoice = Convert.ToInt32(choice);
return intChoice;
}
}
class ProcessMenu
{
public void processMenu(int choice)
{
switch(choice)
{
case 1:
foo1();
break;
case 2:
foo2();
break;
case 3:
foo3();;
break;
default:
Console.WriteLine("Invalid selection. Please select 1, 2, or 3.");
break;
}
}
}
So here's where I'm stuck. I just can't wrap my head around a simple and elegant way validate my user input that's from an OO rather than procedural standpoint.
Assuming I do the validation in the DisplayMenu, I would be validating after the input is read. But if it turns out to be invalid, how do I re-ask for valid input, since I've already called displayMenu method from Main?
I've been playing with while loops for about an hour, something like this:
intChoice = 0;
[print the menu]
while ((intChoice<1) || (intChoice>3))
Console.WriteLine("Please make a valid choice from the menu");
choice = Console.ReadLine();
etc.
but can't seem to find the sweet spot where I can control user input.
I suspect it's because I'm thinking to procedurally, and not object-oriented enough. Anyone have any tips or input to help me wrap my head around this?
Expanding on #AlexeiLevenkov's suggestion of "turning your classes 90 degrees", I went a step further and created this example of a "Modular" console Application:
class Program
{
static void Main(string[] args)
{
//Retrieve all Module types in the current Assembly.
var moduletypes = Assembly.GetExecutingAssembly()
.GetTypes()
.Where(x => x.IsSubclassOf(typeof(ConsoleModule)));
//Create an instance of each module
var modules = moduletypes.Select(Activator.CreateInstance)
.OfType<ConsoleModule>()
.OrderBy(x => x.Id)
.ToList();
int SelectedOption = -1;
while (SelectedOption != 0)
{
//Show Main Menu
Console.Clear();
Console.WriteLine("Please Select An Option:\n");
modules.ForEach(x => Console.WriteLine(string.Format("{0} - {1}", x.Id, x.DisplayName)));
Console.WriteLine("0 - Exit\n");
int.TryParse(Console.ReadLine(), out SelectedOption);
//Find Module by Id based on user input
var module = modules.FirstOrDefault(x => x.Id == SelectedOption);
if (module != null)
{
//Execute Module
Console.Clear();
module.Execute();
Console.WriteLine("Press Enter to Continue...");
Console.ReadLine();
}
}
}
ConsoleModule class:
public abstract class ConsoleModule
{
public int Id { get; set; }
public string DisplayName { get; set; }
public abstract void Execute();
}
Some sample Modules:
public class EnterUserNameModule : ConsoleModule
{
public EnterUserNameModule()
{
Id = 2;
DisplayName = "User Name";
}
public static string UserName { get; set; }
public override void Execute()
{
Console.WriteLine("Please Enter Your Name: ");
UserName = Console.ReadLine();
}
}
public class HelloWorldModule: ConsoleModule
{
public HelloWorldModule()
{
Id = 1;
DisplayName = "Hello, World!";
}
public override void Execute()
{
Console.WriteLine("Hello, " + (EnterUserNameModule.UserName ?? "World") + "!");
}
}
public class SumModule: ConsoleModule
{
public SumModule()
{
Id = 3;
DisplayName = "Sum";
}
public override void Execute()
{
int number = 0;
Console.Write("Enter A Number: ");
if (int.TryParse(Console.ReadLine(), out number))
Console.WriteLine("Your number plus 10 is: " + (number + 10));
else
Console.WriteLine("Could not read your number.");
}
}
Result:
It uses a little bit of reflexion to find all types deriving from ConsoleModule in the current assembly, then shows a menu with all these options (which are actually properties in this class), and calls the Execute() method when an appropiate option is selected. Much more towards OO way of thinking.
Make your processMenu function return some kind of indicator. You could use exceptions for this instead, but that's overkill.
public bool processMenu(int choice)
{
....
}
If the choice was acceptable, then return true, otherwise return false. Then:
public static void Main(String[] args)
{
DisplayMenu thisdm = new DisplayMenu;
ProcessMenu thispm = new ProcessMenu();
int menuChoice;
do {
menuChoice = thisdm.displayMenu();
} while( !thispm.processMenu(menuChoice) );
}
The way you are doing should be changed. Anyhow, for the same as your question, this works out:
DisplayMenu thisdm = new DisplayMenu();
int menuChoice = -1;
while (menuChoice < 1 || menuChoice > 3)
{
Console.WriteLine("enter valid choice");
menuChoice = thisdm.displayMenu();
}
ProcessMenu thispm = new ProcessMenu();
thispm.processMenu(menuChoice);
the code like:
class Program
{
static void Main(string[] args)
{
DisplayMenu thisdm = new DisplayMenu();
ProcessMenu thispm = new ProcessMenu();
thisdm.displayMenu();
int menuChoice = thispm.GetChoice();
thispm.processMenu(menuChoice);
Console.Read();
}
}
class DisplayMenu
{
public void displayMenu()
{
Console.WriteLine("1 - foo3");
Console.WriteLine("2 - foo2");
Console.WriteLine("3 - foo3");
Console.WriteLine("choose");
}
}
class ProcessMenu
{
public int GetChoice()
{
String choice = Console.ReadLine();
int intChoice = Convert.ToInt32(choice);
while (!Validate(intChoice))
{
Console.WriteLine("Invalid selection. Please select 1, 2, or 3.");
choice = Console.ReadLine();
intChoice = Convert.ToInt32(choice);
}
return intChoice;
}
public void processMenu(int choice)
{
switch (choice)
{
case 1:
//foo1();
break;
case 2:
//foo2();
break;
case 3:
//foo3(); ;
break;
default:
//Console.WriteLine("Invalid selection. Please select 1, 2, or 3.");
break;
}
}
private int[] forChoices=new int[]{1,2,3};
private bool Validate(int choice)
{
if(forChoices.Contains(choice))
{
return true;
}
return false;
}
}