インデクサ

プログラミング言語におけるインデクサ （） は、クラスや構造体のインスタンスに配列と同様の添字を指定してアクセスするための構文である。
概要.
言語仕様に配列を持つプログラミング言語の多くは、配列要素にアクセスするための添字による特殊な構文を持つ。例えばC言語から派生した言語では、添え字演算子codice_1により要素アクセスできる。以下はC#の例である。
double[] array = new double[10];
for (int i = 0; i < array.Length; ++i) {
 array[i] = i * 0.1;
System.Console.WriteLine(array[5]);
その一方で、例えば動的配列 (配列リスト) や辞書 (連想配列) などのように、（言語組み込みの）配列以外のデータ構造を持つコレクションオブジェクトの要素に対しても、配列のように添え字でアクセスできると便利かつ直感的である。
インデクサがない言語では通常getterやsetterと呼ばれる要素アクセスのためのメソッドを実装したり、内部の配列をプロパティとして公開するなどしてアクセスするのが一般的であるが、以下の問題点がある。
インデクサを用いることでオブジェクト内のコレクション要素へのアクセスを、配列へのアクセスと同様に記述できる。
ただし、インデクサは実質的にはgetter/setterメソッド呼び出しの糖衣構文であり、インデクサそのものは当然ながら反復子としての機能は持たない。インデクサを記述したからといって配列のようにforeach文などの反復構文がそのまま使えるわけではない他、メソッド呼び出しのオーバーヘッド減少などの効果も特にない（コンパイラによるインライン展開等は当然受けるが、インデクサ固有の利点ではない）。
プログラミング言語C#のインデクサはC++の添え字演算子の多重定義と似ているが、次のような点で発展したものだと見ることもできる。ただしC++とC#の言語設計上の事情も絡んでいるので、単純に比較できるものではない。
他の言語ではC#のインデクサに似た機能として、Visual Basic .NETの引数付きプロパティやC++/CLIのインデックス付きプロパティなどが存在する。
インデクサをサポートしない言語、例えばJavaにおいて、配列リストを表すコレクションの要素へのアクセスは、次のようなcodice_2インターフェイスのget/setメソッドによって提供される。
var list = new java.util.ArrayList<Integer>(java.util.Collections.nCopies(10, 0));
// index 番目の要素に値を設定。
// void set(int index, E element)
list.set(2, 100);
// index 番目の要素を取得。
// E get(int index)
int val = list.get(2);
一方、C#のインデクサでは、配列リストの要素へのアクセスを配列のアクセスと同じように記述することができる。以下の例ではcodice_3インターフェイスで定義されているインデクサを使用している。
var list = new System.Collections.Generic.List<int>(new int[10]);
list[2] = 100;
int val = list[2];
インデクサを定義する際、インデックスとして整数以外の値 (文字列やオブジェクトなど) も使用することができ、ハッシュテーブルなどの連想配列を表すコレクションに使用されている。
var map = new System.Collections.Generic.Dictionary<string, double>();
map["key1"] = 0.1;
double val = map["key1"];
なお、連結リスト実装であるcodice_4は、要素アクセスの計算量が formula_1 ではなく formula_2 であり、インデクサは提供されない。
例.
C#.
C#においては、クラスおよび構造体の内部にインデクサを持つことができる。
インデクサはcodice_5の形式で宣言する。
インデクサの構文内ではcodice_6/codice_7が、codice_7アクセサ内ではcodice_9がそれぞれ文脈キーワードとして機能する。
class Matrix2x2 {
 private readonly int[][] items = new[]{
 new[] { 0, 0 },
 new[] { 0, 0 },
 // セルの値を取得、設定するインデクサ。
 public int this[int index0, int index1] {
呼び出し側では、配列にアクセスするような構文でインデクサの機能を呼び出す。
var matrix = new Matrix2x2();
// setアクセス
matrix[0, 0] = 10;
// getアクセス
int num = matrix[0, 1];
// get ⇒ 加算 ⇒ set
matrix[1, 0] += 10;
通常のメソッドと異なり、代入を伴わないインデクサメソッドの呼び出しは行えない。下記のような呼び出しは構文エラーとなる他、戻り値void型のインデクサを定義することもできない。ただし、インデクサを介して呼び出したオブジェクトのメンバを呼び出すような場合は構文上問題ない。
// 構文エラーとして扱われる。
matrix[1, 0];
// 次の呼び出しは問題ない（この例では意味をなさない呼び出しだが）
matrix[1, 0].ToString();
他言語との相互運用.
他言語との相互運用のため、既定ではcodice_10という名前のインデックス付きプロパティが自動生成される。
codice_11属性を付加することで、自動生成されるインデクサの名前を明示的に指定できる。
この機能が利用されている代表的な例として、codice_12クラスが挙げられる。codice_12クラスではインデクサの名前はcodice_14となるように指定されている。
スニペット.
Visual Studio IDE や Visual Studio Code では、以下のようなコードスニペットが用意されている。
Visual Basic (.NET).
Visual Basic においては、codice_16キーワード付きのインデックス付きプロパティがインデクサとしてアクセス可能となる。
Public Class StringArray
 ' Defaultが宣言されたインデックス付きプロパティはインデクサとしてアクセス可能
 Default Public Property Item(index As Integer) As String
 Get
 Return m_Item(index)
 End Get
 Set(ByVal value As String)
 m_Item(index) = value
 End Set
 End Property
End Class
 Dim obj As StringArray = New StringArray
 ' getアクセス
 Dim str As String = obj(1)
 ' setアクセス
 obj(2) = str