インデクサの小さなサンプル

2024年3月11日

インデクサとは

インデクサとは、クラスや構造体などのインスタンスに対して、配列のようにインデックスを指定してアクセスするための機能です。インデクサを使うことで、配列のように要素を読み書きすることができます。

インデクサは、添え字付きプロパティとも呼ばれます。通常のプロパティと同様に、getアクセサとsetアクセサを定義することができます。インデクサの添え字の型や数は任意で定義することができます。例えば、int型の添え字1つでアクセスするインデクサや、string型の添え字2つでアクセスするインデクサなどがあります。

サンプル

以下は、int型の添え字を使ってアクセスする例です。

コンソール画面に結果は表示されません

MyClass myClass = new MyClass();

myClass[0] = 10;
int x = myClass[0];

public class MyClass
{
    private int[] data = new int[10];

    public int this[int index]
    {
        get { return data[index]; }
        set { data[index] = value; }
    }
}

MyClassクラスにはインデクサーが定義されており、これを使って内部の配列dataにアクセスしています。コードの動作を順に説明します。

  1. MyClass myClass = new MyClass();
    • MyClass型のmyClassという名前のインスタンスを生成しています。
  2. myClass[0] = 10;
    • myClassオブジェクトのインデクサーを使用して、内部配列dataの0番目の要素に10を代入しています。インデクサーのsetアクセサが呼ばれます。
  3. int x = myClass[0];
    • myClassオブジェクトのインデクサーを使用して、内部配列dataの0番目の要素を取得し、それを整数型の変数xに代入しています。この時、インデクサーのgetアクセサが呼ばれます。

MyClassクラスの説明:

  • private int[] data = new int[10];
    • MyClass内にdataという名前のint型の配列をプライベート変数として宣言し、10要素分の領域を確保しています。
  • public int this[int index]
    • これはインデクサーの定義です。インデクサーを使用すると、オブジェクトを配列のように扱うことができます。このインデクサーは整数型のインデックスを受け取り、そのインデックスに対応するdata配列の要素にアクセスします。
      • get { return data[index]; }
        • getアクセサは、指定されたインデックスにある値を返します。
      • set { data[index] = value; }
        • setアクセサは、指定されたインデックスに値を設定します。valueキーワードは、設定される値を表します。

この機能はC#の便利な特性の一つで、オブジェクト内のデータに対する直接的なアクセスを提供しながら、そのデータへのアクセスを制御することができます。インデクサーを使用することで、配列やコレクションへのアクセスをより直感的に行うことが可能になります。

(参考).NETフレームワーク内でインデクサが使われているクラス

.NETフレームワーク内でインデクサが使われているクラスは多数存在します。これらのクラスは、コレクション、リスト、ディクショナリなど、要素の集合を扱う際に特に役立ちます。以下にいくつかの代表的な例を挙げます。

  1. List<T> クラス
    • List<T>は汎用のリストコレクションを表すクラスで、Tはリスト内の要素の型を指定します。インデクサを使用してリスト内の特定の位置にある要素にアクセスできます。
  2. Dictionary<TKey, TValue> クラス
    • Dictionary<TKey, TValue>はキーと値のペアを格納するコレクションです。インデクサを使用して、特定のキーに対応する値にアクセスできます。
  3. Array クラス
    • 配列は.NETの基本的なデータ構造で、固定長の同一型の要素を連続して格納します。インデクサを使用して、任意の位置の要素にアクセスすることができます。
  4. DataTable クラス
    • DataTableはデータのメモリ内表現を提供し、データベースのテーブルのように機能します。行(DataRow)や列(DataColumn)へのアクセスにインデクサを使用することができます。
  5. String クラス
    • Stringクラスもインデクサを使っています。特定の位置にある文字にアクセスするためにインデクサが使用されますが、Stringクラスのインデクサは読み取り専用です。

これらのクラスは、.NETフレームワークで一般的に使用されるデータ構造を扱うためのものであり、インデクサを通じて、要素への簡単かつ直感的なアクセスを提供しています。インデクサを利用することで、コードがより読みやすく、書きやすくなることが多いです。

(学習)Stringクラスでのどのように実装されている?

Stringクラスのインデクサの実装を模倣するサンプルコードを書くことは、Stringクラスの内部動作を理解する上で役立つかもしれません。ただし、実際のStringクラスは.NETフレームワーク内部で高度に最適化されており、ここで示すのはあくまで概念的なシミュレーションです。

以下のコードは、Stringクラスにおける読み取り専用インデクサの振る舞いをシンプルなカスタムクラスで模倣しています。このクラスは、内部にchar型の配列を持ち、インデクサを通じてその配列の特定の要素にアクセスできるようにします。

MyString myString = new MyString("Hello, World!");
char letter = myString[7]; // 8番目の文字にアクセス
Console.WriteLine(letter); // 出力: W

public class MyString
{
    private char[] characters;

    public MyString(string initialString)
    {
        characters = initialString.ToCharArray();
    }

    public char this[int index]
    {
        get
        {
            if (index < 0 || index >= characters.Length)
            {
                throw new IndexOutOfRangeException("Index out of range.");
            }
            return characters[index];
        }
    }
}

このコードは、C#で書かれたシンプルなカスタム文字列クラスMyStringの実装と使用例を示しています。このクラスは、.NETのStringクラスの一部の機能を模倣していますが、基本的な機能のみを持っています。コードの各部分を詳しく説明します。

クラス定義とコンストラクタ

  • public class MyString
    • MyStringという名前のクラスを定義しています。このクラスは、内部的に文字の配列を持ち、与えられた文字列をこの配列に格納します。
  • private char[] characters;
    • char型の配列charactersをプライベート変数として宣言しています。この配列は、クラスのインスタンスに割り当てられた文字列の各文字を保持します。
  • public MyString(string initialString)
    • MyStringクラスのコンストラクタです。文字列を引数として受け取り、その文字列をchar型の配列に変換してcharacters配列に格納します。

インデクサ

  • public char this[int index]
    • クラスにインデクサを定義しています。インデクサは、オブジェクトを配列のように扱うことを可能にします。このインデクサは整数型のindexを引数とし、そのインデックスにある文字を返します。
  • get { ... }
    • インデクサのgetアクセサです。指定されたインデックスが配列の範囲内にある場合は、その位置の文字を返します。範囲外の場合はIndexOutOfRangeExceptionをスローします。

使用例

  • MyString myString = new MyString("Hello, World!");
    • MyStringクラスのインスタンスを作成し、初期文字列"Hello, World!"を渡しています。
  • char letter = myString[7];
    • 作成したmyStringオブジェクトの7番目のインデックス(つまり8番目の文字、プログラミングでは0から数えるため)にアクセスし、その文字(この場合は'W')を変数letterに格納しています。
  • Console.WriteLine(letter);
    • letter変数に格納された文字('W')をコンソールに出力しています。

このコードの目的は、カスタム文字列クラスを定義し、そのクラスのインデクサを通じて特定の文字にアクセスする方法を示すことにあります。このようなカスタムクラスは、.NETの既存のクラスの機能を拡張したり、特定のアプリケーションに特化した動作を実装したい場合に役立ちます。

C#,インデクサ,学習

Posted by hidepon