As you’ve seen in previous chapters, C# allows you to declare arrays, which are accessed using the subscript operator ([]), as shown here:
int [] Ages = { 5, 8, 40, 42 };
Members of the array are accessed using the [] operator, passing the zero-based index of the element to be retrieved:
int firstAge = Ages[0];
Accessing subelements of an array through the [] operator is a common idiom in C and C++ programming. C++ classes that act as containers for other types often provide their own implementation of the operator [] method, allowing access to contained objects using the [] operator, as shown here:
// This is a C++ class, not valid C#. class SmartArray { public: int operator[](int item) { if(item >= 0 && item < arraySize) { return _values[item]; } // Handle error. throw new range_error("invalid index"); } };
Unlike C++, the C# programming language doesn’t allow you to override the operator [] method. Instead, C# allows you to define indexers, which permit your classes and structures to be indexed like arrays. In this chapter, you’ll see how indexers offer a much more powerful and flexible mechanism than the operator [] overloading found in C++. In C#, you can define indexers that accept any number and type of parameters. An indexer is responsible for resolving the arguments passed as subscript parameters and determining the course of action to be taken. As you’ll see later in this chapter, subscript parameters are typically used to identify a contained object. We’ll also look at enumeration, which is another common technique used for accessing collections of objects. By providing support for enumeration, you make your types more usable. For example, enumerable types can be used in the C# foreach statement, as shown here:
foreach(Camper camper in CampingTroop) { camper.MakeMarshmallowVolcano(); }
Classes that support enumeration provide enumeration classes that act as cursors, enabling you to iterate over subitems. In the Microsoft .NET Framework, two interfaces provide a standard infrastructure for enabling enumeration. IEnumerable is implemented by all types that allow themselves to be enumerated, and IEnumerator is implemented by enumeration classes.