12.2.Overloaded Indexers #

Using an integer is a common means of accessing arrays in many languages, but the C# Indexer goes beyond this. Indexers can be declared with multiple parameters and each parameter may be a different type. Additional parameters are separated by commas, the same as a method parameter list. Valid parameter types for Indexers include integers, enums, and strings. Additionally, Indexers can be overloaded. In listing 11-2, we modify the previous program to accept overloaded Indexers that accept different types.
Listing 11-2. Overloaded Indexers: OvrIndexer.cs
using System;

///

/// Implements overloaded indexers.
///
class OvrIndexer
{
    privatestring[] myData;
    privateint         arrSize;

   public OvrIndexer(int size)
    {
        arrSize = size;
        myData = newstring[size];

        for (int i=0; i < size; i++)
        {
            myData[i] = "empty";
        }
    }

    publicstringthis[int pos]
    {
        get
       {
            return myData[pos];
        }
        set
       {
            myData[pos] = value;
        }
    }

    publicstringthis[string data]
    {
        get
       {
            int count = 0;

            for (int i=0; i < arrSize; i++)
            {
                if (myData[i] == data)
                {
                    count++;
                }
            }
            return count.ToString();
        }
        set
       {
            for (int i=0; i < arrSize; i++)
            {
                if (myData[i] == data)
                {
                    myData[i] = value;
                }
            }
        }
    }

    staticvoid Main(string[] args)
    {
        int size = 10;
        OvrIndexer myInd = new OvrIndexer(size);

        myInd[9] = "Some Value";
        myInd[3] = "Another Value";
        myInd[5] = "Any Value";

        myInd["empty"] = "no value";

        Console.WriteLine("\nIndexer Output\n");

        for (int i=0; i < size; i++)
        {
            Console.WriteLine("myInd[{0}]: {1}", i, myInd[i]);
        }

        Console.WriteLine("\nNumber of \"no value\" entries: {0}", myInd["no value"]);
    }
}

Listing 11-2 shows how to overload Indexers. The first Indexer, with the int parameter, pos, is the same as in Listing 11-1, but there is a new Indexer that takes a string parameter. The get accessor of the new indexer returns a string representation of the number of items that match the parameter value, data. The set accessor changes each entry in the array that matches the data parameter to the value that is assigned to the Indexer.
The behavior of the overloaded Indexer that takes a string parameter is demonstrated in the Main() method of Listing 11-2. It invokes the set accessor, which assigns the value of "no value" to every member of the myInd class that has the value of "empty". It uses the following command: myInd["empty"] = "no value";. After each entry of the myInd class is printed, a final entry is printed to the console, indicating the number of entries with the "no value" string. This happens by invoking the get accessor with the following code: myInd["no value"]. Here's the output:
Indexer Output

myInd[0]: no value
myInd[1]: no value
myInd[2]: no value
myInd[3]: Another Value
myInd[4]: no value
myInd[5]: Any Value
myInd[6]: no value
myInd[7]: no value
myInd[8]: no value
myInd[9]: Some Value

Number of "no value" entries: 7
The reason both Indexers in Listing 11-2 can coexist in the same class is because they have different signatures. An Indexer signature is specified by the number and type of parameters in an Indexers parameter list. The class will be smart enough to figure out which Indexer to invoke, based on the number and type of arguments in the Indexer call. An indexer with multiple parameters would be implemented something like this:

    public objectthis[int param1, ..., int paramN]
    {
        get
       {
            // process and return some class data
        }
        set
       {
            // process and assign some class data
        }
    }

Summary
You now know what Indexers are for and how they're used. You can create an Indexer to access class members similar to arrays. Overloaded and multi-parameter Indexers were also covered.

Suggest Edit