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 in C# is a heavily overloaded token that performs unary identity, binary arithmetic addition, string concatenation, delegate combination, enumeration addition, or pointer arithmetic, depending on the static types of its operands. While operator overload resolution and binding occur at compile-time, the actual evaluation of the operation executes at runtime, unless the operands are constant expressions.

Unary Plus Operator

The unary + operator returns the value of its operand. It is predefined for all built-in numeric types.
int unaryOperand = 5;
int unaryResult = +unaryOperand;
System.Console.WriteLine(unaryResult); // Output: 5
Mechanically, the unary + operator performs numeric promotion. For example, applying it to a byte, short, or char implicitly converts the operand to an int.

Binary Arithmetic Addition

When applied to numeric types, the binary + operator computes the sum of its two operands.
int leftInt = 10;
int rightInt = 20;
int sumResult = leftInt + rightInt;
System.Console.WriteLine(sumResult); // Output: 30
  • Numeric Promotion: If the operands are of different types, the compiler applies implicit numeric conversions to align them to a common type before evaluation. Operations on integral types smaller than int (like short or byte) are promoted to int before the addition occurs, returning an int.
  • Integral Overflow Mechanics: For integral types, the behavior upon exceeding the type’s maximum value depends on the execution context. In an unchecked context (the default), the operation wraps around and emits the add Intermediate Language (IL) instruction. In a checked context, it emits the add.ovf IL instruction and throws a System.OverflowException.
  • Floating-Point Mechanics: For float and double, addition is performed according to IEEE 754 arithmetic. Overflow results in positive or negative infinity rather than an exception.
  • Decimal Mechanics: For the decimal type, addition is performed with higher precision and a smaller range than floating-point types. Unlike integral and floating-point types, decimal addition always throws a System.OverflowException if the result exceeds decimal.MaxValue or decimal.MinValue, regardless of whether the operation is in a checked or unchecked context.

String Concatenation

If at least one operand in a binary + operation is of type string, the operator functions as a string concatenator.
string str1 = "Hello, ";
string str2 = "World!";
string concatResult = str1 + str2;
System.Console.WriteLine(concatResult); // Output: Hello, World!
  • Underlying Implementation: The C# compiler translates the + operator into a direct call to the System.String.Concat() method. If multiple + operators are chained, the compiler optimizes this into a single String.Concat call taking an array or multiple arguments to minimize intermediate string allocations.
  • Non-String Operands: For non-string reference types, the compiler emits a call to an overload like System.String.Concat(object, object). The String.Concat method handles null checks internally and invokes ToString() at runtime. This prevents a NullReferenceException if the non-string operand is a null reference. Value types concatenated with strings using the + operator are boxed when passed to System.String.Concat(object, object).

Delegate Combination

When both operands are of the same delegate type, the + operator combines them into a new multicast delegate.
System.Action d1 = () => System.Console.Write("A");
System.Action d2 = () => System.Console.Write("B");
System.Action combined = d1 + d2;
combined(); // Output: AB
System.Console.WriteLine();
  • Underlying Implementation: The compiler translates this operation into a call to System.Delegate.Combine(delegate1, delegate2).
  • Invocation List: The resulting multicast delegate contains an invocation list that executes the left operand’s target method(s) followed by the right operand’s target method(s) sequentially.
  • Null Operands: If one operand is null, the + operator simply returns the non-null delegate instance without creating a new multicast delegate. If both operands are null, the operation returns null.

Enumeration Addition

The C# language specification explicitly defines built-in + operator support for adding an integral type to an enumeration type.
System.DayOfWeek startDay = System.DayOfWeek.Monday;
System.DayOfWeek endDay = startDay + 2;
System.Console.WriteLine(endDay); // Output: Wednesday
  • Underlying Mechanics: The addition is performed on the underlying integral type of the enumeration. The integer operand is added to the underlying value of the enum operand, and the result is cast back to the enumeration type.

Pointer Arithmetic

In an unsafe context, the + operator is natively supported for adding an integer offset to a pointer type.
unsafe 
{
    int[] arr = { 10, 20, 30 };
    fixed (int* ptr = &arr[0])
    {
        int* offsetPtr = ptr + 2;
        System.Console.WriteLine(*offsetPtr); // Output: 30
    }
}
  • Memory Offset: The integer operand is multiplied by the size of the pointer’s target type (in bytes) before being added to the memory address. This operation is only valid for pointers to unmanaged types and cannot be applied to void* pointers, as their size is unknown.

Operator Overloading

User-defined types (class or struct) can overload the + operator to define custom behavior.
Point p1 = new Point(1, 2);
Point p2 = new Point(3, 4);
Point p3 = p1 + p2;
System.Console.WriteLine($"{p3.X}, {p3.Y}"); // Output: 4, 6

public readonly struct Point
{
    public int X { get; }
    public int Y { get; }

    public Point(int x, int y)
    {
        X = x;
        Y = y;
    }

    public static Point operator +(Point left, Point right)
    {
        return new Point(left.X + right.X, left.Y + right.Y);
    }
}
  • Constraints: The overload must be declared as public static. For a binary +, at least one of the parameters must be of the containing type. For a unary +, the single parameter must be of the containing type.
  • Immutability: By convention and design, overloaded + operators should not mutate either operand, but instead instantiate and return a new object representing the result.
Master C# with Deep Grasping Methodology!Learn More