C#
operator overloading
+= operator
programming
object-oriented programming

C operator overload for ?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

In C#, you do not overload += directly for your own type. Instead, you overload +, and the compiler rewrites a += b as a = a + b for normal user-defined types. Understanding that rewrite is the key to getting predictable behavior.

Overload +, Not +=

The language only lets you define specific operators, and compound assignment is not one of them. If your type supports addition, define operator + and let the compiler use it for +=.

csharp
1using System;
2
3public readonly struct Vector2
4{
5    public double X { get; }
6    public double Y { get; }
7
8    public Vector2(double x, double y)
9    {
10        X = x;
11        Y = y;
12    }
13
14    public static Vector2 operator +(Vector2 left, Vector2 right)
15    {
16        return new Vector2(left.X + right.X, left.Y + right.Y);
17    }
18
19    public override string ToString() => $"({X}, {Y})";
20}
21
22public static class Program
23{
24    public static void Main()
25    {
26        var value = new Vector2(1, 2);
27        value += new Vector2(3, 4);
28        Console.WriteLine(value);
29    }
30}

This works because the compiler expands the compound assignment into a regular addition followed by an assignment back to value.

Prefer Immutable Semantics

Operator overloads are easiest to reason about when they behave like built-in numeric types. In other words, + should usually produce a new value instead of mutating one operand.

csharp
1public sealed class Counter
2{
3    public int Value { get; }
4
5    public Counter(int value)
6    {
7        Value = value;
8    }
9
10    public static Counter operator +(Counter left, Counter right)
11    {
12        return new Counter(left.Value + right.Value);
13    }
14}

With this design, counterA += counterB creates a new Counter and assigns it back to counterA. That is much easier to understand than secretly mutating counterA inside operator +.

If mutation is the real goal, a named method such as AddInPlace is usually clearer than a surprising operator overload.

Once a type supports arithmetic operators, people expect the rest of the API to feel consistent. That often means adding equality and useful string output as well.

csharp
1public readonly struct Money
2{
3    public decimal Amount { get; }
4
5    public Money(decimal amount)
6    {
7        Amount = amount;
8    }
9
10    public static Money operator +(Money left, Money right)
11    {
12        return new Money(left.Amount + right.Amount);
13    }
14
15    public static bool operator ==(Money left, Money right)
16    {
17        return left.Amount == right.Amount;
18    }
19
20    public static bool operator !=(Money left, Money right)
21    {
22        return !(left == right);
23    }
24
25    public override bool Equals(object? obj)
26    {
27        return obj is Money other && other.Amount == Amount;
28    }
29
30    public override int GetHashCode()
31    {
32        return Amount.GetHashCode();
33    }
34}

If you define == and !=, always keep them aligned with Equals and GetHashCode. Otherwise dictionaries, sets, and tests may behave inconsistently.

Choose Operators Only When They Match the Domain

Operator overloading is best when the meaning is obvious. Vectors, complex numbers, matrices, and money types often benefit from + because users already understand the operation.

It is a poor fit when the meaning is non-obvious, expensive, or side-effectful. An overloaded operator should not perform network requests, database writes, or logging. Those behaviors are too surprising for something that looks like arithmetic.

Common Pitfalls

The most common mistake is searching for a way to overload += directly. C# does not let you do that. Implement + instead.

Another problem is mutating the left operand inside operator +. That makes a + b look pure while actually changing a, which violates normal caller expectations.

Developers also forget about null handling for reference types. If your operator works on classes, decide what null + value should mean, or reject it clearly with an exception.

Finally, avoid defining operators only because the language allows it. If a named method explains intent better, use the named method.

Summary

  • C# does not support overloading += directly for user-defined types.
  • Implement operator +, and the compiler will use it for compound assignment.
  • Prefer immutable operator behavior so a + b returns a new value.
  • Keep equality members consistent when you add comparison operators.
  • Use operator overloading only when the meaning is obvious and unsurprising.

Course illustration
Course illustration

All Rights Reserved.