# Indexers (C# Programming Guide)

Indexers allow instances of a class or struct to be indexed just like arrays. The indexed value can be set or retrieved without explicitly specifying a type or instance member. Indexers resemble properties except that their accessors take parameters.

The following example defines a generic class with simple get and set accessor methods to assign and retrieve values. The Program class creates an instance of this class for storing strings.

using System;

class SampleCollection<T>
{
// Declare an array to store the data elements.
private T[] arr = new T[100];

// Define the indexer to allow client code to use [] notation.
public T this[int i]
{
get { return arr[i]; }
set { arr[i] = value; }
}
}

class Program
{
static void Main()
{
var stringCollection = new SampleCollection<string>();
stringCollection[0] = "Hello, World";
Console.WriteLine(stringCollection[0]);
}
}
// The example displays the following output:
//       Hello, World.


Note

For more examples, see Related Sections.

## Expression Body Definitions

It is common for an indexer's get or set accessor to consist of a single statement that either returns or sets a value. Expression-bodied members provide a simplified syntax to support this scenario. A read-only indexer can be implemented as an expression-bodied member, as the following example shows.

using System;

class SampleCollection<T>
{
// Declare an array to store the data elements.
private T[] arr = new T[100];
int nextIndex = 0;

// Define the indexer to allow client code to use [] notation.
public T this[int i] => arr[i];

{
if (nextIndex >= arr.Length)
throw new IndexOutOfRangeException(\$"The collection can hold only {arr.Length} elements.");
arr[nextIndex++] = value;
}
}

class Program
{
static void Main()
{
var stringCollection = new SampleCollection<string>();
System.Console.WriteLine(stringCollection[0]);
}
}
// The example displays the following output:
//       Hello, World.


Note that => introduces the expression body, and that the get keyword is not used.

Both the get and set accessor can be implemented as expression-bodied members. In this case, both get and set keywords must be used. For example:

using System;

class SampleCollection<T>
{
// Declare an array to store the data elements.
private T[] arr = new T[100];

// Define the indexer to allow client code to use [] notation.
public T this[int i]
{
get => arr[i];
set => arr[i] = value;
}
}

class Program
{
static void Main()
{
var stringCollection = new SampleCollection<string>();
stringCollection[0] = "Hello, World.";
Console.WriteLine(stringCollection[0]);
}
}
// The example displays the following output:
//       Hello, World.


## Indexers Overview

• Indexers enable objects to be indexed in a similar manner to arrays.

• A get accessor returns a value. A set accessor assigns a value.

• The this keyword is used to define the indexer.

• The value keyword is used to define the value being assigned by the set accessor.

• Indexers do not have to be indexed by an integer value; it is up to you how to define the specific look-up mechanism.