CHAPTER 9 COLLECTIONS AND GENERICS
might extend an abstract base class from the System.Collections or System.Collections.Specialized
namespace):
public class PersonCollection : IEnumerable
{
private ArrayList arPeople = new ArrayList();
// Cast for caller.
public Person GetPerson(int pos)
{ return (Person)arPeople[pos]; }
// Insert only Person objects.
public void AddPerson(Person p)
{ arPeople.Add(p); }
public void ClearPeople()
{ arPeople.Clear(); }
public int Count
{ get { return arPeople.Count; } }
// Foreach enumeration support.
IEnumerator IEnumerable.GetEnumerator()
{ return arPeople.GetEnumerator(); }
}
Notice that the PersonCollection class implements the IEnumerable interface, which allows a
foreach-like iteration over each contained item. Also notice that your GetPerson() and AddPerson()
methods have been prototyped to operate only on Person objects, not bitmaps, strings, database
connections, or other items. With these types defined, you are now assured of type safety, given that the
C# compiler will be able to determine any attempt to insert an incompatible data type:
static void UsePersonCollection()
{
Console.WriteLine("***** Custom Person Collection *****\n");
PersonCollection myPeople = new PersonCollection();
myPeople.AddPerson(new Person("Homer", "Simpson", 40));
myPeople.AddPerson(new Person("Marge", "Simpson", 38));
myPeople.AddPerson(new Person("Lisa", "Simpson", 9));
myPeople.AddPerson(new Person("Bart", "Simpson", 7));
myPeople.AddPerson(new Person("Maggie", "Simpson", 2));
// This would be a compile-time error!
// myPeople.AddPerson(new Car());
foreach (Person p in myPeople)
Console.WriteLine(p);
}
While custom collections do ensure type safety, this approach leaves you in a position where you
must create an (almost identical) custom collection for each unique data type you want to contain. Thus,
if you need a custom collection that can operate only on classes deriving from the Car base class, you
need to build a highly similar collection class:
331