Indexers allow you to index a class or a struct instance in the same way as an array. To declare an indexer, use the following declaration:
[attributes] [modifiers] indexer-declarator {accessor-declarations}
The indexer-declarator takes one of the forms:
type this [formal-index-parameter-list] type interface-type.this [formal-index-parameter-list]
The formal-index-parameter takes the form:
[attributes] type identifier
where:
The get accessor body of an indexer is similar to a method body. It returns the type of the indexer. The get accessor uses the same formal-index-parameter-list as the indexer. For example:
get {
return myArray[index];
}
The set accessor body of an indexer is similar to a method body. It uses the same formal-index-parameter-list as the indexer, in addition to the value implicit parameter. For example:
set {
myArray[index] = value;
}
The type of an indexer and each of the types referenced in the formal-index-parameter-list must be at least as accessible as the indexer itself. For more information on 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.
In order to provide the indexer a name that other languages can use for the default indexed property, use a name attribute in the declaration. For example:
[name ("MyItem")] public int this [int index] { // indexer declaration
This indexer will have the name MyItem
. Without providing the name attribute, the default name will be Item
.
This example declares a private array field myArray and an indexer
. Using the indexer allows direct access to the instance b[i]
. The alternative to using the indexer is to declare the array as a public member and access its members, myArray[i],
directly.
// Indexers using System; class IndexerClass { private int [] myArray = new int[100]; public int this [int index] { // indexer declaration get { // Check the index limits if (index < 0 || index >= 100) return 0; else return myArray[index]; } set { if (!(index < 0 || index >= 100)) myArray[index] = value; } } } public class MainClass { public static void Main() { IndexerClass b = new IndexerClass(); // call the indexer to initialize the elements #3 and #5: b[3] = 256; b[5] = 1024; for (int i=0; i<=10; i++) { Console.WriteLine("Element #{0} = {1}", i, b[i]); } } }
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.
See also the example on Indexers in the language reference, §10.8.