Two versions of both the increment and decrement operators exist and often are a source of confusion. Typically referred to as prefix and postfix, the type of operator indicates when the side effect modifies the variable. With the prefix versions of the increment operator and decrement operator-that is, ++ a and -- a, respectively-the operation is performed and then the value is produced. With the postfix versions of the increment operator and decrement operator-a++ and a--, respectively-the value is produced and then the operation is performed. Take a look at the following example: -
using System; class IncDecApp { public static void Foo(int j) { Console.WriteLine("IncDecApp.Foo j = {0}", j); } public static void Main() { int i = 1; Console.WriteLine("Before call to Foo(i++) = {0}", i); Foo(i++); Console.WriteLine("After call to Foo(i++) = {0}", i); Console.WriteLine("\n"); Console.WriteLine("Before call to Foo(++i) = {0}", i); Foo(++i); Console.WriteLine("After call to Foo(++i) = {0}", i); } }
This application produces this result: -
Before call to Foo(i++) = 1 IncDecApp.Foo j = 1 After call to Foo(i++) = 2 Before call to Foo(++i) = 2 IncDecApp.Foo j = 3 After call to Foo(++i) = 3
The difference here is when the value is produced and the operand is modified. In the call to Foo(++i), the value i is passed (unchanged) to Foo and after the Foo method returns, i is incremented. You can see this in the following MSIL excerpt. Notice that the MSIL add opcode is not called until after the value has been placed on the stack.
IL_0013: ldloc.0 IL_0014: dup IL_0015: ldc.i4.1 IL_0016: add IL_0017: stloc.0 IL_0018: call void IncDecApp::Foo(int32)
Now let's look at the preincrement operator used in the call to Foo(++a). In this case, the MSIL generated looks like the code shown here. Notice that the MSIL add opcode is called before the value is placed on the stack for the subsequent call to the Foo method.
IL_0049: ldloc.0 IL_004a: ldc.i4.1 IL_004b: add IL_004c: dup IL_004d: stloc.0 IL_004e: call void IncDecApp::Foo(int32)