今回は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「演算子のオーバーロード」ページより、複合代入演算子の一覧
ぜひ、他の複合代入演算子についても、同じ要領で試してみてください。
Udemyでの動画版はこちらからご覧いただけます
00_はじめに
01_VisualStudio2026をインストールしてください
A01_fieldキーワード
B01_extensionブロックとは
B02_拡張メソッドとは
B03_extensionブロック
B04_型パラメータありの拡張メソッド
B05_型パラメータありのextensionブロックの書き方
B06_拡張プロパティ
B07_拡張静的プロパティ&メソッド
B08_拡張演算子
C01_partialコンストラクター
C02_幽霊コードを定義パーツで契約による実装をするという考え方
C03_partialイベント
D01_Null条件付き代入
E01_複合代入演算子のオーバーロード
F01_明示的な型を指定せずにラムダパラメータでパラメータ修飾子を使用する
G01_nameofはバインドされていないジェネリック型をサポートします
H01_SpanTおよびReadOnlySpanTのより暗黙的な変換
Udemyでの動画版はこちらからご覧いただけます