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];
public void Add(T value)
{
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>();
stringCollection.Add("Hello, World");
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. Aset
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.
Indexers can be overloaded.
Indexers can have more than one formal parameter, for example, when accessing a two-dimensional array.
Related Sections
C# Language Specification
For more information, see Indexers in the C# Language Specification. The language specification is the definitive source for C# syntax and usage.
See also
Feedback
Submit and view feedback for