Thursday, July 9, 2009

Indexers

1.Indexers enable objects to be indexed in a similar way to arrays.
2.A get accessor returns a value. A set accessor assigns a value.
3.The
this keyword is used to define the indexers.
4.The
value keyword is used to define the value being assigned by the set indexer.
5.Indexers do not have to be indexed by an integer value; it is up to you how to define the specific look-up mechanism.
6.Indexers can be overloaded.
7.Indexers can have more than one formal parameter, for example, when accessing a two-dimensional array.
Indexers allow you to index a
class, struct, or interface in the same way as an array. For more information about using indexers with an interface, see Interface Indexers.
To declare an indexer on a class or struct, use the
this keyword, as in this example:
public int this[int index] // Indexer declaration
{
// 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. For more information about accessibility levels, see Access Modifiers.
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.
To provide the indexer with a name that other languages can use, use a name attribute in the declaration. For example:
[System.Runtime.CompilerServices.IndexerName("TheItem")]
public int this [int index] // Indexer declaration
{
}
This indexer will have the name TheItem. Not providing the name attribute would make Item the default name.
Example 1
The following example shows how to declare a private array field, arr, and an indexer. Using the indexer enables direct access to the instance test[i]. The alternative to using the indexer is to declare the array as a
public member and access its members, arr[i], directly.
C#
class TempRecord
{
// Array of temperature values
private float[] temps = new float[10] { 56.2F, 56.7F, 56.5F, 56.9F, 58.8F,
61.3F, 65.9F, 62.1F, 59.2F, 57.5F };
// Auto-Implemented Property
System.DateTime date { get; set; }
// To enable client code to validate input
// when accessing your indexer.
public int Length
{
get { return temps.Length; }
}
// Indexer declaration.
// Input parameter is validated by client
// code before being passed to the indexer.
public float this[int index]
{
get
{
return temps[index];
}

set
{
temps[index] = value;
}
}
}

class MainClass
{
static void Main()
{
TempRecord tempRecord = new TempRecord();
// Use the indexer's set accessor
tempRecord[3] = 58.3F;
tempRecord[5] = 60.1F;

// Use the indexer's get accessor
for (int i = 0; i < 10; i++)
{
// This example validates the input on the client side. You may
// choose to validate it in the class that implements the indexer, and throw an
// exception or return an error code in the case of invalid input.
if (i < tempRecord.Length)
{
System.Console.WriteLine("Element #{0} = {1}", i, tempRecord[i]);
}
else
{
System.Console.WriteLine("Index value of {0} is out of range", i);
}
}

//Uncomment this code to see how the .NET Framework handles indexer exceptions
//try
//{
// System.Console.WriteLine("Element #{0} = {1}", tempRecord[tempRecord.Length]);
//}
//catch (System.ArgumentOutOfRangeException e)
//{
// System.Console.WriteLine(e);
//}
}
}
Output
Element #0 = 0
Element #1 = 0
Element #2 = 0
Element #3 = 256
Element #4 = 0
Element #5 = 1024
Element #6 = 0
Element #7 = 0
Element #8 = 0
Element #9 = 0
Element #10 = 0
Notice that when an indexer's access is evaluated, for example, in a Console.Write statement, the
get accessor is invoked. Therefore, if no get accessor exists, a compile-time error occurs.