An indexer, in the context of C#, is a class member used to provide array-like indexing capabilities for easy object property access. An indexer is mostly used when an array is encapsulated within a type.
An indexer's simple syntax helps client applications access element groups as an array object member (type, class, or struct). An indexer provides an indirect method of inserting boundary checking logic. Due to its intuitive nature, an indexer improves code readability.
An indexer is often used to implement a stack so that its contents may be accessed without item removal. Java indexer implementation is similar to C#. Generally, indexers could be used in library code, due to their ease of use and flexibility.
Techopedia explains Indexer
Although indexers are similar to properties, they use different parameters. Properties are identified by name, while indexers are denoted by signature and the use of the keyword "this". Properties may be accessed through members, but indexers are accessed through elements. Unlike properties, a C# compiler does not allow static indexer usage.
An indexer is convenient because its class and struct instances are indexed like arrays and use the bracket notation to access an element. Indexers are known as smart arrays. Accessors are the get and set indexer components that enable value fetching and setting, respectively. Based on the member type required for lookup, an indexer is declared with the appropriate signature. The keyword "this" is used to define indexers and "Value" is used to assign the set accessor.
An indexer's type and parameters should be as accessible as the indexer itself. The number and types of formal arguments are known by an indexer's signature, but not type or argument names. The return type should be a valid C# type. An indexer must have at least one parameter.
Class indexers may be overloaded and have different signatures. As indexers are not considered variables, they cannot be used as "ref" or "out" parameters. The cross language uses the default name Item, when not specified in the declaration. Accessors implemented with indexers could be overloaded with multiple types. Indexers allow passing more than one formal parameter, such as in accessing a two-dimensional array. Abstract indexers are implemented by simply declaring the get/set accessors in the base class and adding the derived class code.
Although indexers are also used in interfaces, class declarations differ. Interface indexer accessors do not use modifiers and do not have a body. Indexers are also used in interfaces to indicate whether they are read-only, write-only, or read-write. Per design guidelines, implementing the correct error handling strategy is critical when using the get and set accessors, in addition to providing the required error exception documentation for the indexers. Restricting the accessor to the required level is recommended to avoid malicious set values.