PR

[C# class] インデクサー(indexer)について

クラスメンバーのインデクサーについてです。

インデクサーの機能を使うと配列と同じようにクラスに対して角かっこ [ ] を使い、要素の取得・設定をすることが出来るようになります。

スポンサーリンク

インデクサの使い方

インデクサの定義はこんな感じです。

アクセスレベル 戻り値の型 this[インデックスの型 インデックス名]
{
    アクセスレベル get
    {
        // get は [ ] で要素を取得しようとするときに呼ばれる
        // return を使って呼び出し元に値を返す(型は「戻り値の型」で指定した型)
    }
    アクセスレベル set
    {
        // set は [ ] で要素を設定しようとするときに呼ばれる
        // value という名前の変数に呼び出し元で指定された値が設定されている
        // valueの型は「戻り値の型」で指定した型
    }
}

アクセスレベルにはprivate、publicなどを指定します。
getは外部に公開、setは内部からのみ、などそれぞれ指定することができます。
インデクサ自体のアクセスレベルを省略するとprivate
get、setのアクセスレベルを省略するとpublicになるみたいです。

インデックスの型は [ ] で指定する添え字の型を指定します。
string型にした場合は a[“test”] のように [ ] の中にstring型を指定して要素にアクセスします。

インデックス名はget、set内で使う添え字の名前です。

get は[ ] で要素を取得しようとするときに呼ばれます。 { } 内に returnを使い値を返す処理を書きます。

set は [ ] で要素を設定しようとするときに呼ばれます。{ } 内に処理を書きます。setの{ } 内ではvalueという変数に呼び出し側で指定された値が入っています。

get、setは必ず両方定義する必要はありません。getだけにして読み取り専用setだけにして書き込み専用のインデクサーを定義ことができます。

サンプルコードです。

using System;
using System.Collections.Generic;

class Program
{
    public static void Main()
    {
        var cls = new Sample();

        // [ ] を使って要素を取得しようとするとgetが呼ばれる
        Console.WriteLine(cls[2]);

        // [ ] を使って要素を設定しようとするとsetが呼ばれる
        cls[2] = "z";
        Console.WriteLine(cls[2]);
    }
}

class Sample 
{
    // [ ] でアクセスがあった時に読み書きする用のリスト
    List<string> list = new List<string> { "a", "b", "c", "d" };

    // これがインデクサー
    public string this[int i] 
    {
        // get は [ ] で要素を取得しようとするときに呼ばれる
        get { return this.list[i]; }

        // set は [ ] で要素を設定しようとするときに呼ばれる
        set { this.list[i] = value; }
    }
}

出力結果はこんな感じです。

c
z

get、setの処理が1つの式の場合、=> を使って処理を書くことができます。

using System;
using System.Collections.Generic;

class Program
{
    public static void Main()
    {
        var cls = new Sample();
        Console.WriteLine(cls[2]);
    }
}

class Sample 
{
    // [ ] でアクセスがあった時に読み書きする用のリスト
    List<string> list = new List<string> { "a", "b", "c", "d" };

    // これがインデクサー
    public string this[int i] 
    {
        get => list[i];
        set => list[i] = value;
    }
}
スポンサーリンク

インデックスの型について

上の説明でも書きましたが、インデックスの型は整数(int)である必要はありません。

string型のインデクサーのサンプルです。

using System;
using System.Collections.Generic;

class Program
{
    public static void Main()
    {
        var cls = new Sample();

        cls["a"] = 10;
        cls["b"] = 20;

        Console.WriteLine(cls["a"]);    // 10
        Console.WriteLine(cls["b"]);    // 20
    }
}

class Sample
{
    Dictionary<string, int> dic = new Dictionary<string, int>();

    // これがインデクサー
    public int this[string s] 
    {
        get => this.dic[s];
        set => this.dic[s] = value;
    }
}
スポンサーリンク

複数のインデックスを指定するインデクサー

複数のインデックスを指定するインデクサーも定義できます。

using System;
using System.Collections.Generic;

class Program
{
    public static void Main()
    {
        var cls = new Sample();
        Console.WriteLine(cls[2, 3]);
    }
}

class Sample
{
    // [ ] でアクセスがあった時に読み書きする用
    List<List<string>> list = new List<List<string>> { 
        new List<string> { "a", "b", "c", "d" },
        new List<string> { "e", "f", "g", "h" },
        new List<string> { "i", "j", "k", "l" },
    };

    // これがインデクサー
    public string this[int i, int j] 
    {
        get => list[i][j];
        set => list[i][j] = value;
    }
}
スポンサーリンク

読み取り専用のインデクサー

読み取り専用のインデクサーで値を返すだけなど処理が1つ場合にgetキーワードを省略して書くことができます。

using System;
using System.Collections.Generic;

class Program
{
    public static void Main()
    {
        var cls = new Sample();
        Console.WriteLine(cls[2]);
    }
}

class Sample
{
    // [ ] でアクセスがあった時に読み書きする用のリスト
    List<string> list = new List<string> { "a", "b", "c", "d" };

    // 読み取り専用(getだけ)のインデクサー
    public string this[int i] => this.list[i];
}

C# 記事まとめページに戻る(他のサンプルコードもこちら)

C# プログラミング講座
C#についての記事まとめページです。開発環境VisualStudioのインストール方法や使い方、プログラミングの基礎知識についてや用語説明の記事一覧になっています。講座の記事にはすぐに実行できるようにサンプルコードを載せています。

コメント