1. Eric and the List Objects

Julie needs to go to the store to get some groceries. She goes through her refrigerator, writing down items she needs on a list. When she goes to the store, she refers to the items in her list, marking each one off as she puts it in her cart. At the checkout counter, the clerk takes each item out of Julie's cart, adds its price to the bill, and puts it in a bag. When Julie gets home, she takes each item out of its bag and puts it in her refrigerator. This could be a scene out of the 1950's. Let's bring it up to date. Julie has just purchased a palm computer. She needs some software that will allow her to

She hires Eric, a C# programmer, to write a C# program for her palm computer to manage grocery lists. Eric sits down and thinks about how to solve the problem. His first approach is to create several variables, one variable to hold each item on the list:

string item1, item2, item3, item4, item5;

Right away Eric knows he's in trouble:

He doesn't know in advance how many items Julie will want to put on her list.

Not all of Julie's grocery lists will have the same number of items; sometimes she might only have a list with 3 or 4 items, and another time she might have a list with 30 items.

He has to create enough variables to handle the largest list Julie will need; it's going to be a pain to type all those variable names in. Ever the optimist, Eric presses on with the design for his program, hoping that these difficulties will resolve themselves as he gets into coding.

He decides to create a simple user interface. The program will ask Julie whether she wants to A)dd an item to the list, R)emove an item from the list, or D)isplay the list. After accepting Julie's entry, the program will perform the requested function, then ask for her next command. He sketches more of the program:

using System;
class ListManager {
  static void Main() {
    string item1, item2, item3, item4, item5;

    string command = "";
    while (command != "Q") {
      Console.Write("A)dd item, R)emove item, D)isplay list, Q)uit:");
      command = Console.ReadLine();

      if (command == "A") {
        Console.Write("Enter the item to add to the list: ");
        string newitem = Console.ReadLine();
        Console.Write("Where do you want to put it?");
        int itemnum = Convert.ToInt32(Console.ReadLine());
        if (itemnum == 1) {
          item1 = newitem;
        } else if (itemnum == 2) {
          item2 = newitem;
        } else if ...

      } else if (command == "R") {
        Console.Write("Enter the item # to remove from the list: ");
        int itemnum = Convert.ToInt32(Console.ReadLine());
        if (itemnum == 1) {
          item1 = "";
        } else if (itemnum == 2) {
          item2 = "";
        } else if ...

      } else if (command == "D") {
        Console.WriteLine(item1 + "\n" + item2 + "\n" + item3 + "\n" +
                     item4 + "\n" + item5);
      }
    }
  }
}

Eric now realizes he has some major problems. Julie tells him that she frequently has 30 or 40 items on her list, and he's pretty sure there has to be a better way than creating all those variables and if statements. Also, Julie wasn't crazy about the idea of having to tell the computer which position in the list to add a new item; she just wants to enter the name of the item and let the computer figure out where to put it.

1.1. Eric discovers the List

In desperation, Eric goes to see his friend Marvin who is a C# specialist. Marvin listens as Eric outlines the problem, and nods when Eric expresses a reluctance to create all those variables. "You're absolutely right to look for another approach," Marvin says. "All those variables and all that duplicate code -- your program would be a time bomb waiting to explode."

Marvin then explains that what Eric needs is a collection object -- an object that can hold a bunch of other objects inside it. "Take the List class for example," Marvin says. "It has methods named Add and RemoveAt that you can use to put objects in a list and remove them."

1.2. Creating a List object

To create a List object to store other objects, you write a line of code like this:

List<string> list = new List<string>();

This needs a bit of explanation. List is a class in the System.Collections.Generic namespace. List objects can hold any kind of data, but you have to specify what type of data they contain, by specifying a data type in <angle brackets>. So, the data type of the variable list is List<String>. If you wanted to create a list that holds integers, you would write:

List<int> list = new List<int>();

The list is initially empty.

1.3. Adding Items to a List

Call the Add() method to add an object to the list:

list.Add("Milk");
list.Add("Peanut Butter");
list.Add("Jelly");

The list would look like this:

Slot #Item
0Milk
1Peanut Butter
2Jelly

Notice that each item is at a certain position (slot #) in the list. The slots are numbered beginning at slot 0, just like the characters in a String object are located in positions numbered from 0.

"What if I want to insert an item in the middle of the list?" Eric wondered. "I don't need to do that in this particular application, but there are some other programs where I might want to do that."

"That's easy," answered Marvin. "There's a method called Insert() that allows you to specify where you want to insert the item in the list."

Consider the list above. To insert "Bread" before "Peanut Butter", call Insert() like this:

list.Insert(1, "Bread");

The list would then look like this:

Slot #Item
0Milk
1Bread
2Peanut Butter
3Jelly

As you can see, Insert() "pushes down" the rest of the items to make room. Notice how the list renumbers itself after you insert an item in the list.

1.4. Determining the size of a List

You can use the Count property to find out how many items are in a list:

int numItems = list.Count;

1.5. Accessing items in a List

After you have placed information into a List, you will want to eventually get it back out. To access an item in a List, you use the same notation you use to extract a single character from a string: square brackets -- like this:

string item = list[0]; 

Inside the square brackets, you specify the position number of the item you want. In this case, item would be assigned the value "Milk" -- the value in slot 0 of our list.

Marvin notes, "you have to be careful that you never attempt to access a slot that doesn't exist. For example, if a list has 3 items in it and you try to get the item at slot #3, the system will crash with an ArgumentOutOfRange exception, because the only slots that exist are numbered 0, 1, and 2."

1.6. Displaying List Contents

"Now, take a look at this bit of code and see if you can tell me what it does."

for (int i = 0; i < list.Count; i++) {
  Console.WriteLine(list[i]);
}

"Well, the first time through the loop, i is 0," Eric thinks aloud, "so we get the first item in the list and display it."

"Go on," said Marvin.

"The second time, i is 1, so the second item is displayed. It looks like this code is displaying all the items in the list. Right?"

"That's right!" Marvin applauded. "You can tailor the appearance of the list this way. But tell me this. Why is the loop condition

i < list.Count

instead of

i <= list.Count

?"

Eric again gave the right answer. Can you?

"Notice that a cast is not needed when you're simply displaying an item in a list," Marvin notes.

1.7. Removing items from a List

Use the RemoveAt() method to remove an item from the list. You must know the position of the item in the list:

list.RemoveAt(1); // Removes second item from list

"This method doesn't just blank out the item in slot 1," Marvin observes. "It shifts all the other items in the list up to fill the gap. So if the list looked like this beforehand:

Slot #Item
0Milk
1Peanut Butter
2Jelly

"... it will look like this afterwards:"

Slot #Item
0Milk
1Jelly

1.8. Replacing items in a List

Use square bracket notation to replace an item in the list. For example, if in the example above we wanted to change "Peanut Butter" to "Bread", this code would do the job:

list[1] = "Bread";

The list would then look like this:

Slot #Item
0Milk
1Bread
2Jelly

1.9. An Example

"Now you can write your grocery list manager program," says Marvin. "The List class makes it a piece of cake!"

Example 9.1. ListManager.cs

using System;
using System.Collections.Generic;

class ListManager {
  static void Main() {

    List<string> list = new List<string>();
    
    string command = "";
    while (command != "Q") {
      Console.Write("A)dd item, R)emove item, D)isplay list, Q)uit:");
      command = Console.ReadLine();
      if (command == "A") {
        Console.Write("Enter the item to add to the list: ");
        string newitem = Console.ReadLine();
        list.Add(newitem);

      } else if (command == "R") {
        Console.Write("Enter the item # to remove from the list: ");
        int delitem = Convert.ToInt32(Console.ReadLine());

        list.RemoveAt(delitem); // delete item 

      } else if (command == "D") {
        for (int i = 0; i < list.Count; i++) {
          Console.WriteLine(i + " - " + list[i]);
        }
      }
    }
  }
}

"Wow!" exclaims Eric. "This is a LOT shorter than my first attempt, and it can handle the largest lists Julie will need."

Marvin agrees. "Also, notice that Julie no longer has to enter the position to add a new item. The List puts it at its proper place."