C#  

What are indexers in C#?

Title Image

An indexer in C# is a special type of class or struct member that allows its instances to be accessed like arrays using square brackets ( [ ] ). It acts as a shortcut to expose internal data, such as arrays, lists, or dictionaries, in a clean and intuitive way, making the object behave like a virtual array or key-value store.

Indexers are declared using the this keyword along with at least one parameter and get/set accessors. Unlike properties, which do not take parameters, indexers must take one or more parameters to determine which data element to access or modify.

๐Ÿงช Syntax

[access_modifier] [return_type] this [parameter_list]
{
    get { // return value }
    set { // assign value }
}
  • access_modifier: Usually public
  • return_type: Type of data returned (e.g., int, string)
  • this: Indicates it's an indexer (not a method or property)
  • parameter_list: Type(s) of parameter(s) used to access elements (e.g., int, string)
  • get: Returns the value at the specified index
  • set: Assigns a value to the specified index

๐ŸŽฏ Why Use Indexers?

  • โœ”๏ธ Improves readability: Access data like you access arrays.
  • ๐Ÿ”’ Encapsulates data: Internal implementation is hidden from the user.
  • ๐Ÿงผ Cleaner code: Fewer method calls, more intuitive syntax.
  • ๐Ÿงฐ Custom behavior: Control what happens when getting/setting values.

๐Ÿ‘จ‍๐Ÿ’ป Example: Student Grades (Simple Indexer)

public class StudentGrades
{
    private int[] grades = new int[5];

    public int this[int index]
    {
        get { return grades[index]; }
        set { grades[index] = value; }
    }
}

Usage:

StudentGrades student = new StudentGrades();
student[0] = 85;
Console.WriteLine(student[0]);  // Output: 85

๐Ÿ“’ String-Based Indexer (Like Dictionary)

public class PhoneBook
{
    private Dictionary<string, string> contacts = new();

    public string this[string name]
    {
        get => contacts.ContainsKey(name) ? contacts[name] : "Not Found";
        set => contacts[name] = value;
    }
}

Usage:

PhoneBook pb = new PhoneBook();
pb["Alice"] = "123-4567";
Console.WriteLine(pb["Alice"]); // Output: 123-4567

๐Ÿ” Advanced: Multiple & Overloaded Indexers

public class Indexer
{
    private int[] data = new int[10];

    // Multi-parameter indexer
    public int this[int index, bool square]
    {
        get => square ? data[index] * data[index] : data[index];
        set => data[index] = square ? (int)Math.Sqrt(value) : value;
    }

    // Overloaded indexer with string
    public int this[string key]
    {
        get
        {
            switch (key.ToLower())
            {
                case "first": return data[0];
                case "last": return data[data.Length - 1];
                default: throw new ArgumentException("Invalid key.");
            }
        }
    }

    // Read-only indexer
    public int this[int index]
    {
        get { return data[index]; }
    }
}

Usage:

Indexer i = new Indexer();
i[0, false] = 5;
Console.WriteLine(i[0, false]);  // 5
Console.WriteLine(i[1, true]);   // 0 (0 squared)
Console.WriteLine(i["first"]);   // 5
Console.WriteLine(i[2]);         // 0 (read-only)

๐Ÿงพ Key Points to Remember

๐Ÿ”น Feature ๐Ÿ” Description
this keyword Used to define an indexer in a class
get accessor Retrieves the value at the specified index
set accessor Assigns a value at the specified index using the value keyword
Parameters Must take at least one parameter (unlike properties)
Return type Can be any type, like int, string, object, etc.
Index types Can be int, string, or any type you define
Overloading Multiple indexers with different parameter types are allowed
Multi-dimensional You can define indexers with multiple parameters
Read-only indexer Leave out set to make an indexer read-only
Not static Indexers are always instance members (cannot be static)
Smart arrays Indexers are also called "smart arrays" or "parameterized properties"

๐Ÿงฐ Real-World Use Cases

  • ๐Ÿ“š Student grade systems (index students by ID)
  • ๐Ÿ“ž Phonebook/contact apps (index by name)
  • ๐Ÿ“ฆ Inventory systems (index by SKU)
  • ๐Ÿ”ข Matrix and grid implementations
  • ๐Ÿ”ง Wrapper classes around arrays or dictionaries
  • ๐Ÿ“ Custom data containers or API models

๐Ÿ“ Conclusion

Indexers in C# offer a clean and intuitive way to interact with objects just like arrays or dictionaries. Whether you’re wrapping a collection or building a custom data structure, indexers allow you to expose data safely while improving code readability. With support for multiple parameters, string keys, and overloading, indexers make your C# code more expressive and powerful. If your class needs indexed access, like a collection or mapping, indexers are your go-to feature.