Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

The += operator is the addition assignment operator. It evaluates the addition of the right-hand operand to the left-hand operand and assigns the resulting value to the left-hand operand. At a high level, the expression:
x += y;
is conceptually evaluated as:
x = x + y;
However, there is a critical mechanical distinction: in the compound assignment x += y, the left-hand operand x is evaluated only once. If x represents a complex expression, such as a method call returning an array or a property with side effects, the single evaluation prevents duplicate execution.
// GetIndex() is invoked only once.
array[GetIndex()] += 5; 

// GetIndex() is invoked twice.
array[GetIndex()] = array[GetIndex()] + 5; 

Type-Specific Mechanics

The behavior of the += operator is determined by the types of its operands:
  1. Numeric Types: Performs standard arithmetic addition.
  2. String Types: Performs string concatenation. Because += must assign the result back to the left-hand operand, the left-hand operand must be a type capable of storing a string (such as string, object, or dynamic). When the left-hand operand is a string, a non-string right-hand operand is automatically converted to its string representation. If the left-hand operand is a non-string type (e.g., int) and the right-hand operand is a string, the compiler throws an error because the resulting string cannot be implicitly converted back to the left-hand type. If the right-hand operand is null, C# safely treats it as an empty string (String.Empty) rather than throwing a NullReferenceException.
  3. Delegates and Events: Performs delegate combination. Under the hood, the compiler translates this to a call to System.Delegate.Combine(), which appends the right-hand delegate to the invocation list of the left-hand delegate.

Implicit Casting and Compound Assignment

A significant architectural feature of the += operator is its handling of implicit type conversions. When performing arithmetic on types smaller than int (such as byte or short), the binary + operator implicitly promotes the operands to int. Using the standard addition operator followed by assignment (e.g., a = a + b) requires an explicit cast, but the += operator handles this cast automatically, provided that the right-hand operand y is implicitly convertible to the type of the left-hand operand x. When this condition is met, the compiler translates x += y into x = (T)(x + y), where T is the type of x.
byte a = 10;
byte b = 20;

// This results in a compiler error: Cannot implicitly convert type 'int' to 'byte'.
// a = a + b; 

// This compiles successfully. The compiler generates: a = (byte)(a + b);
a += b; 

int c = 1;
double d = 1.5;

// This results in a compiler error because 'double' is not implicitly convertible to 'int'.
// c += d;

Operator Overloading

The += operator cannot be explicitly overloaded in C#. However, it is implicitly overloaded when a user-defined type overloads the binary + operator. If a struct or class defines a custom + operator, the compiler automatically utilizes that definition when resolving a += expression involving that type.
public struct Vector
{
    public int X;
    
    // Overloading the binary + operator automatically enables += for Vector
    public static Vector operator +(Vector a, Vector b) => new Vector { X = a.X + b.X };
}

Thread Safety and Atomicity

The += operator is not an atomic operation. It represents a logical read-modify-write operation. Even if compiled into a single CISC instruction on x86/x64 architectures (e.g., add dword ptr [memory], value), the CPU performs a sequence of micro-operations on the memory bus without a hardware lock:
  1. Read the value of the left operand.
  2. Add the value of the right operand.
  3. Write the new value back to the left operand.
Because of this read-modify-write cycle, using += on shared variables across multiple threads will lead to race conditions. For thread-safe numeric addition, developers must use System.Threading.Interlocked.Add(). (Note: When += is used to subscribe to an event, it merely invokes the event’s add accessor. The thread safety of this operation depends entirely on how the event is declared. When a field-like event is declared, the C# compiler automatically generates thread-safe add and remove accessors using Interlocked.CompareExchange to ensure thread-safe delegate combination. However, if developers explicitly define custom event accessors, this automatic generation does not apply, and they are responsible for implementing their own thread synchronization.)
Master C# with Deep Grasping Methodology!Learn More