本文へスキップ
BecomeCoder

C#オブジェクト指向コース · 第1章 オブジェクト指向 · レッスン12

インデクサーと演算子オーバーロード

ブラウザで完結

導入

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」へ進みます。

実際に動かしてみよう

本文のサンプルや演習のコードは、コードブロック右上の「コピー」ボタンでコピーして、下のエディタに貼り付ければそのまま実行できます。

C# — ブラウザ内で実行

ブラウザ内でC#を動かす環境を読み込みます(初回のみ数秒)。
スクロールして表示された時点でも自動で読み込まれます。