クラスメンバーのインデクサーについてです。
インデクサーの機能を使うと配列と同じようにクラスに対して角かっこ [ ] を使い、要素の取得・設定をすることが出来るようになります。
インデクサの使い方
インデクサの定義はこんな感じです。
アクセスレベル 戻り値の型 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# 記事まとめページに戻る(他のサンプルコードもこちら)
コメント