|2. Types, Statements and Methods Lab|
Overview: in this lab you'll work with various language features of C# in order to build a simple console-based application.
Part 1: Namespaces and Using
If necessary, open a command window that has the path variables to the .NET Framework SDK set appropriately. Recall that the best way to accomplish this is "Visual Studio .NET Command Prompt" available through the Start menu.
Change directory to the work directory for this lab: cd to where you installed the Labs directory, cd into "2-Types-Stmts-Methods", and then cd into "work".
Copy your Customer class and makefile over from the previous lab into your work directory. Add an integer id field to the Customer class, update the default constructor to input and convert the customer's id, and then update the ToString() method to include the id in the returned string. Finally, wrap the Customer class in a namespace N of your own choosing.
Create a main program in another file, and have it create and output a single customer object to the console. For now, do not wrap the main class in a namespace; as a result you'll need to refer to the Customer class as N.Customer.
For simplicity, modify the makefile so that it builds a monolithic application. This implies the makefile entry should look as follows (in particular, notice that the first line below contains both main.cs and customer.cs, meaning that app.exe depends on both these files):
csc /t:exe /out:app.exe main.cs customer.cs
Compile, run and test.
Add a using statement to the main program file so that you no longer have to type N.Customer when referring to the Customer class. Change each reference of N.Customer to simply Customer. Likewise, add a using statement to the Customer class file and drop the System prefix from your references to the Console and Convert classes. Recompile, run and test.
Part 2: File I/O
Let's move toward an application that inputs customers from a file instead of the keyboard... First, add a parameterized constructor to your Customer class that takes a single parameter named "input" of type System.IO.TextReader. A TextReader denotes a generic input object; for example, the System.Console.ReadLine() method you have been using reads from the TextReader object System.Console.In. Now implement your parameterized constructor so that it inputs a first name, last name, and id number using the given TextReader object; do not prompt for the input, since you don't really know where the input is coming from. When you're done, your parameterized constructor should essentially look like a more general form of your default constructor.
Now test your work by modifying the main program so that when you create a new customer, you pass System.Console.In as the parameter to the constructor. Compile and run --- enter the customer's info as before using the keyboard, only this time you won't be prompted.
Create a text file called "customers.txt" containing two customers. For each customer enter 3 pieces of information, one per line: first name, last name, and id. Modify your main program as follows so that it opens this text file:
sr = new System.IO.StreamReader("customers.txt");
Create two customer objects, passing the StreamReader to the constructor, and output each customer to the console. Run and test; the application should run without any input from the keyboard.
Add a few more customers to the input file, and then place an integer at the top of the file denoting the total number of customers in the file. Declare an array of type Customer in the main program, and then after opening the file, input the first line and convert it to an integer n. Now create the array of size n, and then loop n times, creating Customer objects based on input from the file.
After the input loop, close the file and then use a foreach loop to output each customer to the console. Run and test.
Just for fun, before you output the array, call the System.Array class's Reverse() method and pass it the customers array. Run and test, and the output should now be in reverse order from the input file. Good work!
If time permits...
.NET supports the passing of command-line arguments to applications as you would normally expect. First, add a parameter named "args" of type string to your main program. Next, modify your main program so that if the number of command-line arguments is exactly 1, assume this one argument is the name of the input file and open this file. Otherwise, assume the name of the input file is "customers.txt" as before. Compile and run as before without specifying any command-line arguments; your program should open "customers.txt" as before. Repeat and specify 2 or more command-line arguments; same behavior. Repeat and specify exactly 1 command-line argument, using the name of a file that doesn't exist; your program should now fail with an exception. Finally, make a copy of your "customers.txt" file, modify it, and run your program while specifying this file as a command-line argument; your program should now run correctly, reading its input from the specified file.
The System.Array class contains an IndexOf() method for searching an array for a given object called value. This generic, linear search method operates by comparing value to each object obj in the array; comparison is performed by calling value's Equals method and passing it obj. Modify the main program to input a customer's id from the keyboard, and then create a new customer with this id (you'll probably need to add another constructor to your Customer class, or change the default constructor). Next, call System.Array.IndexOf(), passing it the customers array as well as your new customer object, and save the result of the call into a local integer variable. Output the integer, run and test. Notice the output value is always negative, meaning the search has failed. To fix, add an Equals method to the Customer class that performs comparisons based on customer ids. Now run, and the search should succeed when a valid id is entered by the user.
Take a well-deserved break!