インデクサ

2022年6月26日

インデクサーの概要

  • インデクサーを使用すると、配列と同じようにオブジェクトにインデックスを作成することができます。
  • get アクセサーは値を返します。 set アクセサーは値を割り当てます。
  • this キーワードは、インデクサーの定義に使用されます。
  • value キーワードは、set インデクサーによって割り当てられる値の定義に使用されます。
  • インデクサーは、整数値でインデックスを指定する必要はありません。個々の検索メカニズムの定義方法によります。
  • インデクサーはオーバーロードすることができます。
  • インデクサーには、2 次元配列にアクセスする場合など、複数の仮パラメーターを指定できます。

前提知識

  • 代入演算子
  • 配列
  • オブジェクト指向(クラス、インスタンス)

サンプル

シンプルなサンプル

特徴のあるサンプルを見ていきましょう
まず、利用する側のコードになります。これは、どのような表示になるでしょう?
new()は、new Monster()と同一になります。

サンプルコード

呼び出し側

Monster monsters = new();
int a = monsters[3];

Console.WriteLine(a);

このコードは、エラーになりますね。
monsters変数がMonsterクラスの配列であれば、使えそうですが、そのような設定がありません。
何だか作られたインスタンスが配列扱いできるの?ってことですよね

では、実際のクラスを見ていきましょう
どうでしょう。
Monsterクラスのブロックにgetキーワードがあるので、プロパティにも見えます
ただ、thisというキーワードがプロパティ名のところにあったり、それが配列のようになっていたり、??だらけですね。

thisは、作成されたインスタンスを指すキーワードで、このサンプルでは、monstersになります
続く[]は、配列の状態を表します。
getは、ブロック内に戻り値のあるメソッドを記述するようにします。サンプルでは、int型の戻り値で1を戻り値としています。これは、プロパティと同じ考え方です。なので、setブロックも記述することができます。(今回は省略しています)[]内は、配列では要素番号を記述することのなっていますが、サンプルのように、型(int型)の指定もできるので、string型の指定をすると、文字列でを渡すこともできます。ここは、Dictionaryのようですね。

サンプルコード

インデクサ

class Monster
{
    public int this[int a]
    {
        get
        {
            return 1;
        }
    }
}

サンプル1

もう少し、凝った例を見ていきましょう

サンプルコード

Player型で配列のような呼び出しによってデータを取り出す例になります(次のサンプルは、namespaceブロックやclassブロックが記述されているタイプになります)

using System;
using System.Collections.Generic;
namespace IndexTest
{
    class Program
    {
        static void Main(string[] args)
        {
            Player player = new Player();
            Console.WriteLine(player[0]);
        }
    }
    class Player
    {
        List<string> name = new List<string> { "ファースト", "セカンド" };
        public string this[int number]
        {
            get
            {
                return name[number];
            }
            set
            {
                name[number] = value;
            }
        }
    }
}

実行結果

ファースト

サンプル2

ジェネリックも使った例を見ていきましょう

サンプルコード

using System;
namespace IndexTest
{
    class Program
    {
        static void Main(string[] args)
        {
            Player<int> playerInt = new Player<int>();

            // Playerクラスで宣言されているname配列に数値を代入
            playerInt[0] = 10;

            Console.WriteLine(playerInt[0]);

            Player<string> playerString = new Player<string>();

            // Playerクラスで宣言されているname配列に文字列を代入
            playerString[0] = "ファースト";

            Console.WriteLine(playerString[0]);
        }
    }
    // ジェネリックを使って、型を選べるようにする。
    class Player<T>
    {
        T[] array = new T[2];
        public T this[int number]
        {
            get
            {
                return array[number];
            }
            set
            {
                array[number] = value;
            }
        }
    }
}

実行結果

ファースト

C#

Posted by hidepon