インデクサプログラミング言語におけるインデクサ (英: indexer) は、クラスや構造体のインスタンスに配列と同様の添字を指定してアクセスするための構文である。 概要言語仕様に配列を持つプログラミング言語の多くは、配列要素にアクセスするための添字による特殊な構文を持つ。例えば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文などの反復構文がそのまま使えるわけではない[※ 1]他、メソッド呼び出しのオーバーヘッド減少などの効果も特にない(コンパイラによるインライン展開等は当然受けるが、インデクサ固有の利点ではない)。 プログラミング言語C#のインデクサはC++の添え字演算子の多重定義と似ているが、次のような点で発展したものだと見ることもできる。ただしC++とC#の言語設計上の事情も絡んでいるので、単純に比較できるものではない。
他の言語ではC#のインデクサに似た機能として、Visual Basic .NETの引数付きプロパティやC++/CLIのインデックス付きプロパティなどが存在する。 インデクサをサポートしない言語、例えばJavaにおいて、配列リストを表すコレクションの要素へのアクセスは、次のような 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#のインデクサでは、配列リストの要素へのアクセスを配列のアクセスと同じように記述することができる。以下の例では 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"];
なお、連結リスト実装である 例C#C#においては、クラスおよび構造体の内部にインデクサを持つことができる。 インデクサは インデクサの構文内では class Matrix2x2 {
private readonly int[][] items = new[]{
new[] { 0, 0 },
new[] { 0, 0 },
};
// セルの値を取得、設定するインデクサ。
public int this[int index0, int index1] {
get { return items[index0][index1]; }
set { items[index0][index1] = value; }
}
}
呼び出し側では、配列にアクセスするような構文でインデクサの機能を呼び出す。 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();
他言語との相互運用他言語との相互運用のため、既定では
スニペットVisual Studio IDE や Visual Studio Code では、以下のようなコードスニペットが用意されている。
Visual Basic (.NET)Visual Basic においては、 Public Class StringArray
Private m_Item As String() = New String(10) {}
' 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
注釈
出典関連項目 |