インデクサ
(Indexer (programming) から転送)
出典: フリー百科事典『ウィキペディア(Wikipedia)』 (2022/05/20 14:21 UTC 版)
ナビゲーションに移動 検索に移動プログラミング言語におけるインデクサ (英: indexer) は、クラスや構造体のインスタンスに配列と同様の添字を指定してアクセスするための構文である。
概要
言語仕様に配列を持つプログラミング言語の多くは、配列要素にアクセスするための添字による特殊な構文を持つ。例えばC言語から派生した言語では、添え字演算子[]
により要素アクセスできる。以下は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と呼ばれる要素アクセスのためのメソッドを実装したり、内部の配列をプロパティとして公開するなどしてアクセスするのが一般的であるが、以下の問題点がある。
- コードの冗長化による可読性や直感性の低下
- 言語によってはgetやsetが識別子として扱われている場合があり、アクセサメソッドの名前が冗長化しやすい
- 内部配列(実装)を外部に公開するようなパターンは(カプセル化の観点から)そもそも避けるべきである
インデクサを用いることでオブジェクト内のコレクション要素へのアクセスを、配列へのアクセスと同様に記述できる。
ただし、インデクサは実質的にはgetter/setterメソッド呼び出しの糖衣構文であり、インデクサそのものは当然ながら反復子としての機能は持たない。インデクサを記述したからといって配列のようにforeach文などの反復構文がそのまま使えるわけではない[※ 1]他、メソッド呼び出しのオーバーヘッド減少などの効果も特にない(コンパイラによるインライン展開等は当然受けるが、インデクサ固有の利点ではない)。
プログラミング言語C#のインデクサはC++の添え字演算子の多重定義と似ているが、次のような点で発展したものだと見ることもできる。ただしC++とC#の言語設計上の事情も絡んでいるので、単純に比較できるものではない。
- インデクサではプロパティのように値を得るときと代入するときとで実際には別のメソッドに分かれている。
- インデクサは単独で多次元な配列を模倣できる。C++で同じようなことをするには間に一時的にオブジェクトを入れるなどの技巧を凝らす必要がある[要説明]。
他の言語ではC#のインデクサに似た機能として、Visual Basic .NETの引数付きプロパティやC++/CLIのインデックス付きプロパティなどが存在する。
インデクサをサポートしない言語、例えばJavaにおいて、配列リストを表すコレクションの要素へのアクセスは、次のようなjava.util.List
[※ 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#のインデクサでは、配列リストの要素へのアクセスを配列のアクセスと同じように記述することができる。以下の例ではSystem.Collections.Generic.IList
インターフェイスで定義されているインデクサを使用している。
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"];
なお、連結リスト実装であるSystem.Collections.Generic.LinkedList
は、要素アクセスの計算量が
- Indexer (programming)のページへのリンク