導入
list[0]の[]や、a + bの+は、標準の型だけの特権ではありません。インデクサーを定義すれば自作クラスもobj[キー]で書け、演算子オーバーロードを定義すれば+や==を自作型に持たせられます。数値ライクな型(金額・座標・ベクトル)を自然に書けるようになります。
図解
flowchart LR
I["インデクサー<br/>this[int i]"] --> IU["obj[0] と書ける"]
O["演算子オーバーロード<br/>operator +"] --> OU["a + b と書ける"]
サンプル
// 演算子オーバーロード: 2次元ベクトルの足し算を + で書けるようにする
struct Vector
{
public int X { get; }
public int Y { get; }
public Vector(int x, int y) { X = x; Y = y; }
public static Vector operator +(Vector a, Vector b) => new Vector(a.X + b.X, a.Y + b.Y);
public override string ToString() => $"({X}, {Y})";
}
var v = new Vector(1, 2) + new Vector(3, 4);
Console.WriteLine(v); // (4, 6)
// インデクサー: 自作クラスを obj[i] でアクセスできるようにする
class Week
{
private string[] _days = { "日", "月", "火", "水", "木", "金", "土" };
public string this[int i] => _days[i]; // これがインデクサー
}
var week = new Week();
Console.WriteLine(week[3]); // 水
- 演算子オーバーロードは
public static 戻り値 operator +(...)の形で定義する + - * == <などを自作型に持たせ、数値のように自然に書ける- インデクサーは
public 型 this[引数]で定義し、obj[キー]でアクセスできる - やり過ぎると読みにくくなるので、「自然に見える型」に限って使う
演習
var a = new Yen(300);
var b = new Yen(500);
// TODO: Yen に + の演算子オーバーロードを定義し、a + b が 800円 になるようにしてください
Console.WriteLine(a + b);
struct Yen
{
public int Value { get; }
public Yen(int value) { Value = value; }
public override string ToString() => $"{Value}円";
___
}
- 期待される出力:
800円
ヒント1を見る
public static Yen operator +(Yen a, Yen b) => new Yen(a.Value + b.Value);
ヒント2を見る
上の1行をYenの中に加えるとa + bが書けます
まとめ
- 演算子オーバーロード(
operator +など)で自作型に演算子を持たせられる - インデクサー(
this[...])でobj[キー]アクセスを実現できる - 「自然に見える」型に限定して使うのがコツ
次章: データを簡潔に表す型「record・struct・enum」へ進みます。