In C#, indexers allow instances of a class or struct to be indexed like arrays, enabling easy access to data within an object using array-like syntax. This provides a more intuitive and clean way to access internal collections or properties without explicitly calling a method. Indexers make it possible to treat classes that represent collections in a way similar to arrays.
An indexer is essentially a property that allows you to access elements in an object through an index. Similar to arrays, indexers use the []
brackets, but rather than accessing elements by position in memory, they access them through defined logic within a class. Indexers are useful when creating custom collections or containers within a class, providing direct access to elements without additional method calls.
To define an indexer in C#, you use the this keyword followed by an index parameter in square brackets. The return type of an indexer defines what type of data the indexer will handle. An indexer can have both get and set accessors, just like properties.
Here is the basic syntax for defining an indexer:
public class ClassName
{
private int[] numbers = new int[5]; // Example internal array
// Indexer
public int this[int index]
{
get { return numbers[index]; }
set { numbers[index] = value; }
}
}
In this example, the indexer allows access to the numbers array within the class using the syntax object[index]
.
With an indexer defined, you can access elements within an object instance using an array-like syntax.
Let’s create a StudentRecords
class where each student's score is accessible via an indexer.
public class StudentRecords
{
private string[] students = new string[3]; // Array to store student names
// Indexer to access student names
public string this[int index]
{
get
{
if (index < 0 || index >= students.Length)
throw new IndexOutOfRangeException("Invalid Index");
return students[index];
}
set
{
if (index < 0 || index >= students.Length)
throw new IndexOutOfRangeException("Invalid Index");
students[index] = value;
}
}
}
Here’s how to use this indexer:
public class Program
{
public static void Main()
{
StudentRecords studentRecords = new StudentRecords();
// Setting values using indexer
studentRecords[0] = "John";
studentRecords[1] = "Alice";
studentRecords[2] = "Bob";
// Accessing values using indexer
Console.WriteLine(studentRecords[0]); // Output: John
Console.WriteLine(studentRecords[1]); // Output: Alice
Console.WriteLine(studentRecords[2]); // Output: Bob
}
}
This allows StudentRecords
objects to be used in an array-like manner, adding simplicity to code that needs to access or update student records.
Imagine a library system where each library branch holds a collection of books. Each book has an ID
, and we want a straightforward way to access or modify book details using an indexer.
We need a way to:
Using an indexer within the Library
class, we can manage books by accessing them directly through an index.
public class Book
{
public string Title { get; set; }
public string Author { get; set; }
public Book(string title, string author)
{
Title = title;
Author = author;
}
}
public class Library
{
private Book[] books = new Book[10];
// Indexer to access books in the library
public Book this[int index]
{
get
{
if (index < 0 || index >= books.Length)
throw new IndexOutOfRangeException("Invalid book index.");
return books[index];
}
set
{
if (index < 0 || index >= books.Length)
throw new IndexOutOfRangeException("Invalid book index.");
books[index] = value;
}
}
}
Library
ClassNow, we can add and retrieve books in a library using simple, array-like syntax:
public class Program
{
public static void Main()
{
Library library = new Library();
// Adding books to the library
library[0] = new Book("1984", "George Orwell");
library[1] = new Book("To Kill a Mockingbird", "Harper Lee");
// Accessing book details via indexer
Console.WriteLine($"Book 1: {library[0].Title} by {library[0].Author}");
Console.WriteLine($"Book 2: {library[1].Title} by {library[1].Author}");
}
}
In this example:
Library
class with a Book[]
array to store books.Book
using an index, managing retrieval and updates with a clean syntax.Indexers in C# are powerful tools for creating classes that work like arrays, allowing data within classes to be accessed using indices. They improve code readability, offer enhanced encapsulation, and simplify data manipulation within custom collections. In scenarios like a library system, indexers allow for cleaner, array-like syntax, making them ideal for situations where collection-like behavior is required. Embracing indexers can lead to more organized, readable, and maintainable code, especially when working with custom collections or managing multiple related items.