[C#] 22. インデクサー(indexer)を使う方法


Study / C#    作成日付 : 2019/07/13 01:06:04   修正日付 : 2021/09/03 17:21:01

こんにちは。明月です。


この投稿はC#のインデクサー(indexer)を使う方法に関する説明です。


C#には他の言語にはない文法が何個かあります。

その中で一つが以前の投稿で説明したプロパティ(Property)です。

link - [C#] 21. C#のプロパティ(Property)

この投稿もC#の特別な文法のインデクサー(indexer)です。

インデクサー(indexer)は簡単に説明すると配列の形で関数を呼び出す機能です。文法の形はプロパティ(Property)と似てます。

using System;
using System.Collections.Generic;
 
namespace Example
{
  // Indexerの例クラス
  class Node
  {
    // メンバー変数
    private List<string> data = new List<string>();
    // これがインデクサー(indexer)の文法
    // 関数名にはthisキーワードを入れて、パラメータを配列の形の大括弧で設定する。
    public int this[string keyword]
    {
      // インデクサーのget
      get
      {
        // 該当なキーワードの位置を返却
        for (int i = 0; i < data.Count; i++)
        {
          // パラメータのkeywordとメンバー変数リストのオブジェクトアイテムと同じ値なら
          if (string.Equals(data[i], keyword))
          {
            // リストの位置を返却
            return i;
          }
        }
        // キーワードが無ければ-1を返却
        return -1;
      }
      // インデクサーのset
      set
      {
        // リストから該当なデータ(keyword)を取り除く。
        data.Remove(keyword);
        // リストでindexに該当なⅠにデータを追加
        data.Insert(value, keyword);
      }
    }
    // 出力関数
    public void Print()
    {
      // メンバー変数リストの順番で
      foreach (var d in this.data)
      {
        // コンソール出力
        Console.WriteLine(d);
      }
    }
  }
  class Program
  {
    // 実行関数
    static void Main(string[] args)
    {
      // Nodeインスタンス生成
      Node node = new Node();
      // インデクサー(indexer)は配列みたいに使う。
      // 大括弧のデータはインデクサーのパラメータ、値はvalueに設定
      node["Hello"] = 0;
      node["World"] = 1;
      // コンソール出力
      node.Print();
      // 改行
      Console.WriteLine();
      // インデクサーのset関数を利用してHelloのリスト位置を変更
      node["Hello"] = 1;
      // インデクサーのget関数を利用してHelloの配列位置を確認
      Console.WriteLine(node["Hello"]);
      // 改行
      Console.WriteLine();
      // コンソール出力
      node.Print();
      // 任意のキーを押してください
      Console.WriteLine("Press any key...");
      Console.ReadKey();
    }
  }
}


上の例をみれば私がNodeクラスでインデクサー(indexer)関数を作りました。

インデクサー(indexer)はプロパティの文法みたに配列の値を受け取るデータタイプと入力するデータタイプを設定して関数名にはthisキーワードを使います。

そして配列みたいに使うので、配列のインデクサー役でString値を格納するし、イコールでデータは返却データタイプで値を格納します。


Mainの実行関数でnode[string] = intの形で実装するとset関数が呼び出すし、node[string]の型で実装するとget関数が呼び出します。

文法がプロパティ(Property)と似てます。なのでアクセス修飾子を設定する方法も似てますが、基本のアクセス修飾子はgetで設定して、set関数だけ別途にアクセス修飾子を設定することができます。

using System;
using System.Collections.Generic;
 
namespace Example
{
  // Indexerの例クラス
  class Node
  {
    // メンバー変数
    private List<string> data = new List<string>();
    // コンストラクタ(可変パラメータでデータを受け取る)
    public Node(params string[] datas)
    {
      for (int i = 0; i < datas.Length; i++)
      {
        this[datas[i]] = i;
      }
    }
    // これがインデクサー(indexer)の文法
    // 関数名にはthisキーワードを入れて、パラメータを配列の形の大括弧で設定する。
    public int this[string keyword]
    {
      // インデクサーのget
      get
      {
        // 該当なキーワードの位置を返却
        for (int i = 0; i < data.Count; i++)
        {
          // パラメータのkeywordとメンバー変数リストのオブジェクトアイテムと同じ値なら
          if (string.Equals(data[i], keyword))
          {
            // リストの位置を返却
            return i;
          }
        }
        // キーワードが無ければ-1を返却
        return -1;
      }
      // インデクサーのset(アクセス修飾子をprivateで設定)
      private set
      {
        // リストから該当なデータ(keyword)を取り除く。
        data.Remove(keyword);
        // リストでindexに該当なⅠにデータを追加
        data.Insert(value, keyword);
      }
    }
    // 出力関数
    public void Print()
    {
      // メンバー変数リストの順番で
      foreach (var d in this.data)
      {
        // コンソール出力
        Console.WriteLine(d);
      }
    }
  }
  class Program
  {
    // 実行関数
    static void Main(string[] args)
    {
      // Nodeインスタンス生成
      Node node = new Node("Hello", "World");
 
      // コンソール出力
      node.Print();
      // Worldの位置を出力
      Console.WriteLine(node["World"]);
 
      // 任意のキーを押してください
      Console.WriteLine("Press any key...");
      Console.ReadKey();
    }
  }
}


プロパティ(Property)とインデクサー(Indexer)は他の言語にはない文法です。

この文法があることはオブジェクト指向プログラミング(OOP)のカプセル化により、メンバー変数をprivateに設定しますが、ゲッター、セッターを少し効率的に格納、取得するための文法です。

でも、プロパティの場合はよく使いますが、インデクサー(Indexer)はよく使いません。なぜかというと配列と似ている形なので、逆に迷う時が発生します。

ソースコードは可読性、つまり、ソースを読みやすく作ることが重要ですが、インデクサー文法が多いソースは逆に迷い込みやすいです。そのことでよく使わないですね。

特にC#だけ開発するデベロッパー(開発者)の方はインデクサー(Indexer)が凄く読みやすいっていうかもしれませんが、JavaやPythonなどの他の言語がメインのデベロッパー(開発者)の方は難しいというかもしれません。

その理由かな、実務プロジェクトでもよく見えない文法です。


ここまでC#のインデクサー(indexer)を使う方法に関する説明でした。


ご不明なところや間違いところがあればコメントしてください。

#C#
最新投稿