C#14新機能

C#14 新機能 E01_複合代入演算子のオーバーロード

今回はC# 14で追加された「複合代入演算子のオーバーロード」を扱います。Visual Studio 2026を起動し、新しいプロジェクトの作成からWindowsフォームアプリを選択します。名前と場所を決め、対象フレームワークは.NET 10を選択します。

図1 新しいプロジェクトの作成

複合代入演算子とは

複合代入演算子とは、+=や-=のように「代入」と「演算」を同時に行う演算子のことです。たとえばint型であれば、a += 1と書くとaに1が足されます。

ただし、これがオブジェクト同士の場合はどうなるでしょうか。次のようなCounterクラスを用意します。Value という int 型のプロパティを1つだけ持ち、コンストラクターで値を受け取って設定します。

図2 Counterクラスの定義

従来の演算子オーバーロード(+演算子)

Counterオブジェクトを2つ用意し、c1とc2をそのまま「c1 + c2」のように足そうとすると、コンパイルエラーになります。オブジェクト同士を足すと言われても、コンパイラはどうしていいか分からないためです。

図3 演算子 ‘+’ を ‘Counter’ と ‘Counter’ 型のオペランドに適用することはできません(CS0019)

そこで、Counterクラスの中に「+演算子が使われたときはこう動いてほしい」という定義を書いておくと、+演算子が使えるようになります。これはC# 14より前から使えた書き方です。

図4 public static Counter operator +(Counter a, Counter b) の定義

public class Counter
{
    public Counter(int value)
    {
        Value = value;
    }
 
    public int Value { get; set; }
 
    public static Counter operator +(Counter a, Counter b)
    {
        return new Counter(a.Value + b.Value);
    }
}

 

この定義により、「Counter と Counter の足し算はこう動く」という動作を定義したことになり、c1 + c2 という書き方ができるようになります。c1のValueが1、c2のValueが10のとき、c3 = c1 + c2 を実行するとc3のValueは11になります。

図5 c3 = c1 + c2 実行後、operator + が新しいCounterを返している

ポイントは、この+演算子はstaticなメソッドとして定義されている点です。static なので、Counterクラスの中にはあっても、Counterが保持しているValueに直接アクセスすることはできず、新たにCounterをnewして返す必要があります。

C# 14で追加された複合代入演算子のオーバーロード(+=演算子)

C# 14からは、+=演算子もオーバーロードできるようになりました。次のように定義します。

図6 public void operator +=(Counter other) の定義(+演算子との違いに注目)

public class Counter
{
    public Counter(int value)
    {
        Value = value;
    }
 
    public int Value { get; set; }
 
    public static Counter operator +(Counter a, Counter b)
    {
        return new Counter(a.Value + b.Value);
    }
 
    public void operator +=(Counter other)
    {
        this.Value += other.Value;
    }
}

 

ポイントは、この+=演算子はインスタンスメソッドになっているところです。+演算子はstaticなメソッドでしたが、+=の方はインスタンスメソッドなので、Valueと同じ場所にあり、thisで自分自身のValueにアクセスできます。そのため、投げられてきたCounterのValue(other.Value)を自分自身のValue(this.Value)に足し込むことができます。

これにより、c1 += c2 という書き方ができるようになります。c1がthisとして扱われ、c2がotherとして渡されます。自分自身のValueと渡されてきたValueを足すだけなので、このような書き方になります。

重要なのは、インスタンスメソッドになったことで、新たにインスタンスを生成していないという点です。先ほどの+演算子の書き方では、c3という新しいオブジェクトをnewする必要がありました(staticなメソッドで新たなオブジェクトをnewして返していたため)。一方、+=の方はthisで自分自身の値を書き換えるだけなので、新たなオブジェクトを生成しません。そのぶん、パフォーマンス的にも有利になります。

実際に実行してみると、c1のValueが11になっていることが確認できます。c1 += c2によって、Value同士の足し算が行われ、11という結果になっています。

図7 c1 += c2 実行後、c1.Value が 11 になっている

オーバーロードできる複合代入演算子の一覧

複合代入演算子は+=以外にも複数あり、C# 14以降ではそれらもオーバーロードできます。Microsoft Learnの公式ドキュメントには、+=、-=、*=、/=、%=、&=、|=、^=、<<=、>>=、>>>= がC# 14以降でオーバーロード可能である旨が記載されています。

図8 Microsoft Learn「演算子のオーバーロード」ページより、複合代入演算子の一覧

ぜひ、他の複合代入演算子についても、同じ要領で試してみてください。

C#14 新機能