Previously, compound assignment operators like += and -= were always desugared by the compiler into the corresponding binary operator and assignment. For example, x += y became x = x + y. This meant the type had no control over the compound assignment and could not optimize it.
C# 14 allows types to define compound assignment operators directly, enabling in-place mutation that avoids allocating a new instance.
Code
csharp
using System.Text;
var buffer = new TextBuffer("Hello");
buffer += " World"; // Calls the custom += operator, mutates in place
public class TextBuffer
{
private StringBuilder sb;
public TextBuffer(string text) => sb = new StringBuilder(text);
// Custom compound assignment: an instance method that appends in place
public void operator +=(string right)
=> sb.Append(right);
// Binary operator still needed for x = a + b
public static TextBuffer operator +(TextBuffer left, string right)
=> new TextBuffer(left.sb.ToString() + right);
}csharp
using System.Text;
var buffer = new TextBuffer("Hello");
buffer = buffer + " World"; // Always creates a new instance
public class TextBuffer
{
private StringBuilder sb;
public TextBuffer(string text) => sb = new StringBuilder(text);
// += always desugared to: buffer = buffer + " World"
public static TextBuffer operator +(TextBuffer left, string right)
=> new TextBuffer(left.sb.ToString() + right);
}Notes
- Compound assignment operators are
void-returning instance methods with a single parameter (notstatic), so they mutatethis - Defining
+=does not define+; if a type only declares+, thenx += ystill falls back tox = x + y - Instance
++and--operators can also be declared, e.g.public void operator ++() - Particularly useful for collection-like types or builders where creating a new instance per operation is wasteful
- See Checked user-defined operators C# 11.0 for the checked and unchecked behaviour that carries over to the compound assignment form.