【C#】図で理解するインデクサの基礎

当ページのリンクには広告が含まれています。

C#には、添え字で各要素にアクセスできる配列(Array、Listなど)や辞書(Dictionary)があります。

自作のクラスにおいても、これらと同様に添え字でクラス内部のデータにアクセスできる仕組み=インデクサが用意されています。

知っていると便利な機能なので、今回はインデクサの作り方、使い方、注意点について解説したいと思います。

目次

インデクサとは

通常の配列 ( int[] )や、リスト(List)、辞書(Dictionary)などのクラスは、内部に保持しているデータを添え字で指定することが出来ます。

この添え字の事を「インデックス」と呼んでいますが、配列やListの場合は先頭0から始まる数字、辞書の場合は文字列(Key)でアクセスしたい要素の場所を指定します。

この機能を独自のクラスで使えるようにすること、言い換えると独自クラスの中に保持しているデータを、外部から添え字でアクセスさせる方法を「インデクサ」と呼びます。

インデクサの作り方

インデクサは一か所を除いて通常のプロパティと全く同じ記述で作成することが出来ます。

違いは、変数名の部分を this[型 変数名] という具合に記述するところです。

下記のソースコードは MyClass というクラスにインデクサを作った例です。

この例では、内部では Values というList型の変数に文字列列が保持されています。

仮に、先頭から4番目(添え字=3)の要素にアクセスしたい場合、通常のプロパティでは Values[3]という記述をしますが、インデクサを作成していれば、クラス名[3] という記述ができるようになります。

インデクサの添え字は文字、数字に限らない

先ほどの例では、配列と同じく数値でクラス内部のデータにアクセスしましたが、添え字は数値だけという制限はありません。

クラス内部に辞書(Dictionary)を保持している場合は、インデクサとして文字列型を使うケースの方が多と思います。

文字列、数値以外に、オブジェクト型や任意のクラスをインデクサの添え字で使う事もできます。

次のソースは、オブジェクト型のインデクサのサンプルになります。

オブジェクトのインデクサを使う場合のサンプルソースを掲載しておきます。

インデクサをオブジェクト型にすると、添え字として整数や文字列、文字列などが使える様になりますが、逆に添え字として何を与えたらよいのかが不明確なってしまいます。

このように、あまり複雑な事をすると訳が分からなくなってしまいますので、特に必要が無い限り数値や文字列くらいに留めておく方が無難です。

インデクサの添え字は2個でも3個でも可能

インデクサの添え字は1つだけではなく、複数指定することが出来ます。

例えば、次のサンプルはインデクサの引数を2つ持たせた例です。

このインデクサは次の様にして使うことが出来ます。

添え字が2個以上になってしまうと、やはり何を添え字に使えばよいのか直感的に分からなくなるので、あまり多用はしない方がよさそうです。

インデクサには独自の処理が記述できる

ここまでに提示したサンプルは、クラス内部に保持しているリストや辞書の内容を、インデクサを使ってアクセスするという例でした。

しかし、インデクサの仕様としては、指定されたインデクサとして指定された変数の値に対応した結果を返したり、受け取ったりすれば良いだけなので、必ずしもリストや辞書の結果を返す必要はありません。

例えば、下記のインデクサは、添え字として指定された値を二乗して、結果を文字列として返しています。

内部にデータを保持する必要が無いため、set には何も記述していません。

このインデクサは次の様に利用できますが、この様に添え字に対応する結果を返せば中身は何でもよいことがお分かりいただけるかと思います。

インデクサの注意点

インデクサは独自のクラス内部にあるデータに対して、外部から配列と同じ様にアクセスさせるための方法です。

あたかも配列と同じ様に扱えるという事は、使う側も配列と同じ様に結果が返されることを期待しているわけです。

つまり、添え字に5を入れると、先頭から数えて6番目の要素が取り出せることを期待しますし、文字列であれば辞書の様にキーが一致した時の値が取り出せることを期待します。

インデクサを作る場合も、使う側の期待を裏切らないような結果を返す処理にすべきです。

また、配列の様にアクセスすることは可能なものの、配列と同じという事ではありません。

例えば、配列が持っているLength等のプロパティやSelectやToList、SumなどのLinqは使えませんし、配列を処理する場合に使う Arrayクラスを使ってコピーやソートをすることも出来ません

配列の様に添え字にアクセスできますが、あくまでも疑似的な物で配列とは別物であるという事は意識しておいて下さい。

まとめ

インデクサは独自クラスの内部に保持している値を、外部から添え字でアクセスするための方法です。

プロパティの型指定の部分が this[型 変数名] という記述になる点を除けば、通常のプロパティと同じ記述で作ることが出来ます。

インデクサは、渡された添え字に対応する値を受け取ったり、返したりするものなので、中身はリストや辞書のように値を保持する代わりに、ロジックを記述することも可能です。

インデクサの添え字の型や個数に制限は無く、オブジェクト型の添え字や、添え字の数を2以上作ることも可能ですが、分かり難くなるという弊害もあります。

あくまでも配列と同じ様にクラス内部のデータにアクセスできますが、配列が持つLengthやLinqが使は使えません。

以上の事を踏まえておけば、あとは実戦あるのみです。

使いこなせば便利な機能なので、是非ご活用ください。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次