We have previously reviewed the techniques of creating
and using an array. The main problem of traditional C++ arrays is that their size is fixed
by the number you specify when declaring the array variable: you cannot add
items beyond the specified dimension. Another limitation is that you cannot
insert an item inside the list. To overcome this, you can create a linked list.
Instead of working from scratch, the .NET Framework provides the ArrayList class.
With the ArrayList class, you can add new items to a list, insert items inside a
list, arrange items of a list, check the existence
of an item in a list, remove an item from the list, inquire about the list,
or destroy the list. These operations are possible through various properties and methods.

The ArrayList class is defined in the System::Collections
namespace. To use it, first declare a pointer to ArrayList. Here is
an example:

The primary operation performed on a list is to create
one. One of the biggest advantages of using a linked list is that you
don't have to specify in advance the number of items of the list as done for an
array. You can just start adding items. The ArrayList class makes this
possible with the
Add() method. Its syntax is:

public: virtual int Add(Object *value);

The argument of this method is the value to add to the list.
If the method succeeds with the addition, it returns the position where the
value was added in the list. This is usually the last position in the list. Here
are examples:

If
the method fails, the compiler would throw an error. One of the errors that
could result from failure of this operation would be based on the fact that
either a new item cannot be added to the list because the list is read-only, or
the list was already full prior to adding the new item.

As you can create a array list that includes any value
of type Object, you can also create your own class and use it to create a
list based on the ArrayList class. To use your own class, when
creating it, make sure it is created as a managed object. Here is an example:

After declaring an ArrayList variable, it may be empty.
As objects are added to it, the list grows. The list can grow tremendously as
you wish. The number of items of the list is managed through the memory it
occupies and this memory grows as needed. The number of items that the memory
allocated is currently using is represented by the ArrayList::Capacity
property. This will usually be the least of your concerns.

If for some reason, you want to intervene and control the
number of items that your ArrayList list can contain, you can manipulate
the Capacity property. For example, you can assign it a constant to set
the maximum value that the list can contain. Once again, you will hardly have any
reason to use the Capacity property: the compiler knows what to do with
it.

A Fixed Size List

A list is usually meant to grow and shrink as necessary.
This also lets the compiler manage the memory occupied by the list. In some
cases, you may want a list to have a fixed size. To set this flag, you can call
the ArrayList::FixedSize() method. It is overloaded in two versions. One
of them has the following syntax:

public: static ArrayList* FixedSize(ArrayList* list);

If you set a fixed size on an ArrayList list, you may
not be able to add a new item beyond the limit. In fact, if you attempt to do
this, you may receive an error. A safe way is to check whether the list is fixed
before performing a related operation. To find out whether a list is fixed, you
can check the ArrayList::IsFixedSize property.

The Number of Items in the List

When using a list, at any time, you should be able to know
the number of items that the list contains. This information is provided by the ArrayList::Count
property. The Capacity and the Count have this in common: the value of each
increases as the list grows and the same value decreases if the list shrinks. It
is important to know that, although they look alike, there are various
differences between the capacity of a list and the number of items it contains. Capacity
is a read/write property. This means that, as we saw above, you can assign a
value to the capacity to fix the number of items that the list can contain. You
can also retrieve the value of the Capacity. The Count is read-only
because it is used by the compiler to count the current number of items of the
items and this counting is performed without your intervention.

Practical
Learning: Counting Items

To get a count of items while the user is adding them to the list, change
the Click event of the Add Item button as follows:

When using the Add(), the AddRange(), or the Insert()
methods to populate an ArrayList object, the item or the group of items is added
to the end of the list in a consecutive manner. If you want to reverse this
arrangement, you can call the Reverse() method. This method is provided
in two versions. One of the versions has the following syntax:

public: virtual void Reverse();

This method considers all items of a list and changes their
positions in the exact opposite order: the first item becomes the last; the item
before last becomes the second in the new list, and so on. If you want to
reverse only a range of items in the list, you can use the other version of this
method whose syntax is:

public: virtual void Reverse(int index, int count);

In some cases, you may want the list to be arranged in an
order validated by the language used on the computer. For example, if you create
a list of names, you may want to display those names in alphabetical order. If
you create a list of employees, you may want to display the list of employees by
seniority, based on the date they were hired. The ability to arrange the list in
a set order can be handled by the Sort() method. Its syntax is:

public: virtual void Sort();

If the items in the list are made of strings, this method
would arrange them in alphabetical order. If the items are numeric values,
calling this method would arrange the list in incremental order. If the list is
made of dates, when this method is called, the compiler would refer to the
options set in the Regional Settings of the Control and arrange them accordingly
in chronological order.

A Read-Only List

One of the reason for creating a list is to be able to add
items to it, edit its items, retrieve an item, or delete items from it. These
are the default operations. You can still limit these operations as you judge
them unnecessary. For example, you may create a list and then initialize it with
the items that you want the list to only have. If you don't intend to have the
user adding items to it, you can create the list as read-only. To do this, you
can call the ArrayList::ReadOnly() method. It is overloaded with two
static versions as follows:

These methods are static. This means that you don't need to
declare an instance of ArrayList to call them. Instead, to make the list
read-only, call the ArrayList::ReadOnly() method and pass your ArrayList
variable to it.

Some operations cannot
be performed on a read-only list. To perform such operations, you can first find
out whether an ArrayList list is read-only. This is done by checking its IsReadOnly
property.

Item Retrieval

Once a list is ready, you can perform different types of
operations on it. Besides adding items, one of the most regular operations
performed on a list consists of locating and retrieving an item. You have
various options. To retrieve a single item based on its position, you can use the
Item property which accesses each item using square brackets. Like a normal array, an ArrayList
list is zero-based. Another issue to keep in mind is that the ArrayList::Item[]
property produces an Object value. Therefore, you may have to cast this value to your type
of value to get it right. Here are examples of using this property:

Instead of the square brackets that allow you to retrieve an
item based on its position, you can look for an item based on its complete
definition. You have various options. You can first "build" an item
and ask the compiler to check whether any item in the list matches your
definition. To perform this search, you can call the ArrayList::Contains()
method. Its syntax is:

public: virtual bool Contains(Object *item);

The item to look for is passed as argument to the method.
The compiler would look for exactly the item, using its definition, in the list.
If any detail of the argument fails to match any item of the ArrayList
list, the method would return false. If all characteristics of the argument
correspond to an item of the list, the method returns true.

Another option to look for an item in a list consists of
calling the ArrayList::BinarySearch() method. It is overloaded in three
versions and one of them uses the following syntax:

public virtual int BinarySearch(object value);

The item to look for is passed argument to the method.

Item Deletion

As opposed to adding an item to a list, you may want to
remove one. To perform this operation, you have various options. You can ask the
compiler to look for an item in the list and if, or once, the compile finds it,
it would delete the item. To perform this type of deletion, you can call the ArrayList::Remove()
method. Its syntax is:

public virtual void Remove(object obj);

This method accepts as argument the item that you want to
delete from the list. To perform this operation, the list must not be read-only.

The Remove() method allows you to specify the exact
item you want to delete from a list. Another option you have consists of
deleting an item based on its position. This is done using the RemoveAt()
method whose syntax is:

public virtual void RemoveAt(int index);

With this method, the position of the item is passed as
argument. If the position is not valid because either it is lower or higher than
the current Count, the compiler would throw an ArgumentOutOfRangeException
exception.

To remove all items from a list at once, you can call the ArrayList::Clear()
method. Its syntax is: