Back to Blog
C#

C# Prefix vs Postfix Increment

Understand how C#'s prefix (++i) and postfix (i++) increment operators differ, including evaluation order, return values, and practical examples.

C# operatorsincrement operatorsexpression evaluationcode readability
A visual comparison of prefix and postfix increment operators in C#, showing the timing of the increment relative to value usage.

Understanding the difference between ++i and i++ in C# is important because the two forms behave differently inside expressions. Although they look similar, choosing the wrong one can introduce subtle bugs. Consider this minimal example:

int i = 5; int a = i++; // a is 5, i becomes 6 int j = 5; int b = ++j; // b is 6, j becomes 6

The postfix form i++ returns the original value of i before incrementing it. The prefix form ++j increments the variable first and then returns the new value. Both forms modify the variable, but the value they produce in the surrounding expression is different. This article explains the evaluation order, the side effects, and when each form is appropriate.

Evaluation Order in Prefix vs Postfix

In C#, the increment operator has a side effect: it modifies the variable it operates on. The difference lies in when that side effect is visible to the rest of the expression.

  • Postfix (i++): The expression evaluates to the current value of i, and then i is incremented. The increment happens after the value is read.
  • Prefix (++i): The variable is incremented first, and then the expression evaluates to the new value.

This distinction becomes critical when the increment appears inside a larger expression. For example:

int i = 1; int result = i++ + i++; // result is 3, i becomes 3

The first i++ evaluates to 1, then i becomes 2. The second i++ evaluates to 2, then i becomes 3. The sum is 1 + 2 = 3. If you used prefix operators instead:

int i = 1; int result = ++i + ++i; // result is 5, i becomes 3

The first ++i increments i to 2, then evaluates to 2. The second ++i increments i to 3, then evaluates to 3. The sum is 2 + 3 = 5. The result differs because the timing of the increment changes the value used in the addition.

Using Increment in Method Calls and Indexers

Increments often appear as arguments or inside index expressions. The same evaluation order applies.

int index = 0; Process(items[index++]); // passes items[0], then index becomes 1

Here, items[index++] selects the element with the current value of index and then increments index before the method call. If you used ++index, you would select items[1] and end with index = 1. This pattern is common when iterating through a collection manually, and the choice changes which element is processed.

Side Effects and Readability

Both forms produce a side effect. Postfix evaluates to the old value and then increments the variable; prefix increments the variable and then evaluates to the new value. In isolation, as a standalone statement like i++; or ++i;, both produce the same final variable value. The only observable difference is the value returned by the expression. Therefore, in a standalone statement, either form is functionally equivalent.

Most C# developers use i++ as a standalone increment because it is the conventional syntax from C-style languages. However, inside a larger expression, the choice matters and can affect correctness. For example:

while (i < items.Length) { Console.WriteLine(items[i++]); // outputs current, then increments }

If you wrote ++i here, you would skip the first element and eventually access an index out of bounds. This is a practical example where the postfix form is required for correct behavior.

The Return Value Difference

The key difference is the return value. The postfix operator returns the original value; the prefix operator returns the incremented value. For int variables, this is a semantic difference, not a meaningful performance reason to choose one over the other. The real cost is the cognitive load when reading code that uses the wrong operator in an expression.

Common Mistakes in Compound Expressions

Understand that the right-hand side of x = i++; is the original value of i, and evaluating that expression also increments i. The assignment uses that original value. If you need x to receive the incremented value, use x = ++i;.

Another common mistake is mixing prefix and postfix in a single expression:

int i = 0; int result = ++i + i--; // result is 2, i becomes 0

Here, ++i makes i 1, then i-- evaluates to 1 and decrements i back to 0. The result is 2. This is hard to read and easy to get wrong. Such expressions should be split into separate statements for clarity.

Performance Considerations

There is no meaningful performance difference between prefix and postfix for simple integer variables. For primitive types like int or long, any difference is negligible. For custom types that overload the ++ operator, postfix increment can require preserving the original value while updating the variable, so it may involve an extra copy for large value types or types with expensive copying. If you do not need the original value in the same expression, prefix avoids that potential extra copy.

When to Use Which Form

Use prefix when you need the incremented value in the same expression, such as while (++i < limit). Use postfix when you need the original value, such as when passing an element to a method and then advancing the index. For standalone increment statements, the choice is personal or team preference, but consistency within a codebase improves readability. Avoid using both forms in the same complex expression because it is difficult to follow the evaluation order.

A practical pattern for a for-loop is the postfix form i++, which is idiomatic and reads naturally. In a while-loop where the condition uses the increment, prefix is often clearer:

int i = 0; while (++i < 10) { Console.WriteLine(i); }

This loop prints numbers 1 through 9. If you changed the condition to i++ and kept the same body, the body would run after the increment, so the loop would print 1 through 10. The condition would compare the original value, but the body would see the updated value.

Compatibility and Language Versions

The behavior of prefix and postfix increment is well-defined across all C# versions. It is part of the language specification and does not change between versions. The same semantics apply to variables of built-in numeric types, enums, and custom types that overload the operators. For custom types, the operator overload defines the behavior, but the evaluation order remains the same.

Final Practical Example

A common real-world scenario is iterating over an array and accumulating values. The choice of increment operator directly affects which elements are examined.

int[] values = { 10, 20, 30 }; int current = 0; int sum = 0; while (current < values.Length) { int value = values[current++]; // use current, then increment sum += value; } Console.WriteLine(sum); // 60

If you replaced current++ with ++current, the loop would increment current before reading the array. It would skip values[0], read values[1] and values[2], then attempt to read values[3] when current reaches the length, causing an IndexOutOfRangeException. The difference is subtle but meaningful. Understanding the return value of each operator is the key to writing correct code in these situations.

C# Prefix vs Postfix Increment: ++i vs i++ Explained | RYUSLOG DEV