Indexer access

For an indexer access, the primary-no-array-creation-expression of the element-accessmust be a variable or value of a class, struct, or interface type, and this type must implement one or more indexers that are applicable with respect to the expression-list of the element-access.
The compile-time processing of an indexer access of the form P[A], where P is a primary-no-array-creation-expression of a class, struct, or interface type T, and A is an expression-list, consists of the following steps: The set of indexers provided by T is constructed. The set consists of all indexers declared in T or a base type of T that are not override declarations and are accessible in the current context (10.5). The set is reduced to those indexers that are applicable and not hidden by other indexers. The following rules are applied to each indexer S.I in the set, where S is the type in which the indexer I is declared: If I is not applicable with respect to A (14.4.2.1), then I is removed from the set. If I is applicable with respect to A (14.4.2.1), then all indexers declared in a base type of S are removed from the set. If the resulting set of candidate indexers is empty, then no applicable indexers exist, and a compile-time error occurs. If the candidate indexers are not all declared in the same type, the indexer access is ambiguous, and a compile-time error occurs (this latter situation can only occur for an indexer access on an instance of an interface that has multiple direct base interfaces). The best indexer of the set of candidate indexers is identified using the overload resolution rules of 14.4.2. If a single best indexer cannot be identified, the indexer access is ambiguous, and a compile-time error occurs. The index expressions of the expression-list are evaluated in order, from left to right. The result of processing the indexer access is an expression classified as an indexer access. The indexer access expression references the indexer determined in the step above, and has an associated instance expression of P and an associated argument list of A.
Depending on the context in which it is used, an indexer access causes invocation of either the get-accessor or the set-accessor of the indexer. If the indexer access is the target of an assignment, the set-accessor is invoked to assign a new value (14.13.1). In all other cases, the get-accessor is invoked to obtain the current value (14.1.1).