C#には「インデクサ(Indexer)」という非常に便利な機能があります。
これは、クラスや構造体のインスタンスに配列のようなアクセス方法を提供する構文です。
たとえば「オブジェクト名[インデックス]」のように記述することで、まるで配列の要素にアクセスするかのように、クラス内部のデータにアクセスできるのです。
本記事では、インデクサの基本的な書き方から、get/setの使い分け、活用例、さらには実務での使いどころまでを丁寧に解説します。C#でオブジェクト設計をしている方や、コードの表現力を高めたい方におすすめの内容です。
インデクサとは何か?
C#におけるインデクサ(Indexer)とは、クラスや構造体のオブジェクトに対して配列のようなアクセス方法を可能にする特別なプロパティです。
通常、オブジェクトのフィールドやプロパティにアクセスするには「obj.PropertyName」という形式を使いますが、インデクサを定義すると「obj[index]」のような配列的なアクセスができるようになります。
構文の基本
class Sample
{
private string[] names = new string[10];
public string this[int index]
{
get { return names[index]; }
set { names[index] = value; }
}
}
この例では、Sampleクラスのインスタンスに対して sample[0] = "Alice";
のような使い方が可能になります。
インデクサの構成要素とルール
インデクサはプロパティに似ていますが、次のような違いがあります。
- インデクサは
this
キーワードを使って定義します。 - インデクサは、引数を受け取る点がプロパティと異なります。
- アクセス修飾子(public/privateなど)や戻り値の型、get/setブロックなどはプロパティと同じように使えます。
定義の構文
[アクセス修飾子] 戻り値の型 this[引数]
{
get { ... }
set { ... }
}
インデクサは複数定義することも可能で、オーバーロード(引数の型や数が異なるインデクサ)も利用できます。
実用例:名前付きコレクション
たとえば、社員の名前リストを管理するクラスを考えてみましょう。
class EmployeeDirectory
{
private Dictionary<int, string> employees = new Dictionary<int, string>();
public string this[int id]
{
get
{
return employees.ContainsKey(id) ? employees[id] : "未登録";
}
set
{
employees[id] = value;
}
}
}
使い方:
var directory = new EmployeeDirectory();
directory[101] = "田中";
Console.WriteLine(directory[101]); // 出力:田中
このように、インデクサを使えば辞書のような操作をクラスを通して自然に行うことができます。
読み取り専用・書き込み専用のインデクサ
インデクサもプロパティ同様、get/setを片方だけ実装することで読み取り専用または書き込み専用にすることが可能です。
読み取り専用の例
public int this[int index]
{
get { return data[index]; }
}
書き込み専用の例
public int this[int index]
{
set { data[index] = value; }
}
読み取り専用にすることで、不用意なデータの書き換えを防ぐことができます。
複数引数のインデクサ
インデクサは、1つのインデックスだけでなく、複数の引数を受け取ることも可能です。
例えば、2次元配列のようなアクセスも可能です。
public int this[int row, int col]
{
get { return matrix[row, col]; }
set { matrix[row, col] = value; }
}
このようなインデクサを定義すれば、以下のような記述ができます。
matrix[1, 2] = 5;
インデクサの利点と注意点
利点
- コードが直感的で読みやすくなる
- 外部からのアクセス方法を統一できる
- クラスのカプセル化を保ちつつ、柔軟なデータ操作が可能になる
注意点
- インデクサの内部実装によってはパフォーマンスに影響することもある
- 意味のある名前(プロパティ名)ではなくインデックスアクセスなので、APIとしての可読性が落ちる場合がある
- 多用しすぎると、クラスの設計が不明瞭になるおそれがある
実務での活用シーン
インデクサは以下のような場面で活躍します。
- 独自のコレクションクラスの実装
- 外部ライブラリへのアクセスをラップする際の簡易的なインターフェース
- 設定情報やキャッシュの取得時に「キー」を使ったアクセスが求められるとき
たとえば、設定情報クラスをインデクサでラップすると以下のように使いやすくなります。
var config = new ConfigSettings();
Console.WriteLine(config["AppMode"]);
まとめ
C#のインデクサは、クラスに「配列のような使いやすさ」を付与できる強力な機能です。
シンプルに見えて奥深く、柔軟なアクセス制御を設計に取り入れたい場面で重宝します。
ただし、インデクサの使いどころを見極めないと、逆にクラスの設計がわかりにくくなることもあります。
そのため、「インデクサを使う理由」が明確なときにこそ、その力を最大限に活かせるといえるでしょう。