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, formally known as the null-coalescing assignment operator, assigns the value of its right-hand operand to its left-hand operand strictly if the left-hand operand evaluates to null. If the left-hand operand is not null, the operator performs no assignment and bypasses the evaluation of the right-hand operand.
leftOperand ??= rightOperand;

Technical Characteristics

1. Single Evaluation of the Left-Hand Operand The ??= operator guarantees that the left-hand operand is evaluated exactly once. While the operation is conceptually similar to if (a is null) { a = b; }, the ??= operator is technically distinct and safer for expressions involving side effects. If the left-hand operand includes a method call or an indexer, it is not re-evaluated for the assignment.
string?[] array = new string?[5];
int index = 0;
int ComputeIndex() => index++;

// ComputeIndex() is evaluated exactly once.
// 'index' increments to 1, whereas an 'if' construct would increment it to 2.
array[ComputeIndex()] ??= "Assigned";
2. Short-Circuit Evaluation The ??= operator employs short-circuiting. The right-hand operand is evaluated only if the left-hand operand is determined to be null. If the left-hand operand holds a value, the right-hand expression is entirely ignored, preventing potential side effects or performance costs associated with evaluating the right side.
string? text = "Initial Value";
string ComputeDefault() => "Default Value";

// ComputeDefault() is never executed because 'text' is not null.
text ??= ComputeDefault(); 
3. Return Value and Type Resolution The ??= operation is an expression that yields a result. The operator does not re-evaluate the left-hand operand’s getter after the assignment completes; the result of the right-hand evaluation is yielded directly. The type of the evaluated expression depends on the types of the operands:
  • If the left-hand operand is of a nullable value type T? and the right-hand operand is of type T (or implicitly convertible to T), the type of the ??= expression evaluates directly to the underlying non-nullable type T.
  • For all other cases, the type of the expression is the type of the left-hand operand.
int? nullableInt = null;

// The expression (nullableInt ??= 5) evaluates to type 'int', not 'int?'.
// This allows direct assignment to a non-nullable variable without casting.
int result = (nullableInt ??= 5); 
4. Type Constraints
  • Left-hand operand: Must be a variable, property, or indexer element. Its type must be a reference type, a nullable value type (Nullable<T>), or an unconstrained generic type parameter. If an unconstrained generic type parameter resolves to a non-nullable value type at runtime, the left-hand operand will never evaluate to null, and the assignment will simply never occur.
  • Right-hand operand: Must be of a type that is implicitly convertible to the type of the left-hand operand (or implicitly convertible to the underlying type T if the left-hand operand is a nullable value type T?).
5. Thread Safety The ??= operator is not atomic. It executes as a discrete read operation followed by a conditional write operation. In multithreaded scenarios, a race condition can occur if another thread modifies the left-hand operand between the null check and the assignment. 6. Language Version The operator was introduced in C# 8.0. Attempting to use it in environments targeting older compiler versions will result in a syntax error.
Master C# with Deep Grasping Methodology!Learn More