Most sources says that overloading ++ and -- operators in c# results overloading both, postfix and prefix at once. But it looks like their behaviour is still different.
This is the wrong way to implement increment and decrement in C#. You will get crazy results if you do it wrong; you did it wrong, you got crazy results, so the system works. :-)
Coincidentally I wrote an article about this very subject last week:
http://ericlippert.com/2013/09/25/bug-guys-meets-math-from-scratch/
As commenter dtb points out, the correct implementation is:
public static Counter operator ++(Counter c)
{
return new Counter(c.v + 1);
}
In C# the increment operator must not mutate its argument. Rather it must only compute the incremented value and return it, without producing any side effects. The side effect of mutating the variable will be handled by the compiler.
With this correct implementation your program now goes like this:
Counter c1 = new Counter(1);
Call the object that c1 refers to right now W
. W.v
is 1.
Counter c2 = c1++;
This has the semantics of:
temp = c1
c1 = operator++(c1) // create object X, set X.v to 2
c2 = temp
So c1
now refers to X
, and c2
refers to W
. W.v
is 1 and X.v
is 2.
Counter c3 = ++c1;
This has the semantics of
temp = operator++(c1) // Create object Y, set Y.v to 3
c1 = temp
c3 = temp
So c1 and c3 now both refer to object Y
, and Y.v
is 3.
c3++;
This has the semantics of
c3 = operator++(c3) // Create object Z, set Z.v to 4
So when the smoke all clears:
c1.v = 3 (Y)
c2.v = 1 (W)
c3.v = 4 (Z)
and X
is orphaned.
This should give exactly the same results as if you'd had c1
, c2
and c3
as normal integers.