Sunday, September 27, 2009

C# Indexers

Indexers permit instances of a class or struct to be indexed in the same way as arrays. Indexers are similar to properties except that their accessors take parameters. To declare an indexer on a class or struct, use the “this” keyword as shown below:

// Indexer declaration
public int this[int index]    
{
    // get and set accessors
}

The type of an indexer and the type of its parameters must be at least as accessible as the indexer itself. The signature of an indexer consists of the number and types of its formal parameters. It does not include the indexer type or the names of the formal parameters. If you declare more than one indexer in the same class, they must have different signatures. An indexer value is not classified as a variable; therefore, it is not possible to pass an indexer value as a ref or out parameter.

// Using a string as an indexer value
class DayCollection
{
    string[] days = { "Sun", "Mon", "Tues", "Wed", "Thurs", "Fri", "Sat" };

    // This method finds the day or returns -1
    private int GetDay(string testDay)
    {
        int i = 0;
        foreach (string day in days)
        {
            if (day == testDay)
            {
                return i;
            }
            i++;
        }
        return -1;
    }

    // The get accessor returns an integer for a given string
    public int this[string day]
    {
        get
        {
            return (GetDay(day));
        }
    }
}

class Program
{
    static void Main(string[] args)
    {
        DayCollection week = new DayCollection();
        System.Console.WriteLine(week["Fri"]);
        System.Console.WriteLine(week["Made-up Day"]);
    }
}

*  Indexers enable objects to be indexed in a similar way to arrays.
*  A get accessor returns a value. A set accessor assigns a value.
*  The “this” keyword is used to define the indexers.
*  The value keyword is used to define the value being assigned by the set indexer.
*  Indexers do not have to be indexed by an integer value; it is up to you how to define the specific look-up mechanism.
*  Indexers can be overloaded.
*  Indexers can have more than one formal parameter, for example, when accessing a two-dimensional array.

There are two main ways in which the security and reliability of indexers can be improved:
*  Always ensure that your code performs range and type checks when setting and retrieving values from any buffer or array accessed by the indexers.
*  Set the accessibility of the get and set accessors to be as restrictive as is reasonable. This is important for the set accessor in particular.

No comments: