Yes and no.
The answer is yes in the sense that this:
i++;
is equivalent to this:
i = i + 1;
which would be equivalent to this (if System.Int32
had a constructor with this signature):
i = new int(i + 1);
BUT...
A constructor for a value type in .NET is in no way the same as a reference type constructor.
The space for a value type is allocated once on the stack. When you write i = i + 1
, this is simply writing a new value to the same location in memory. It is not a new allocation on the heap.
This is in fact an implementation detail; but that doesn't change the fact that the answer to what I think you're really asking -- "Does writing i++
require allocating some new memory somewhere?" -- the answer to that question is no.
So, to clarify a few points:
Does increment always create new instances and discard the old ones?
No -- this demonstrates a misunderstanding of the way value types work. It would only make sense to say that incrementing a value "discards the old one" if value types were allocated in some space other than the local stack. It is true that the old value is overwritten, but I hardly think you would find that surprising.
By the way, is increment thread-safe? In documentation, it says all the members of Int32 are thread-safe . . .
Where the documentation says that all members of Int32
are thread-safe, it means with respect to the current value. In fact, any immutable type is going to be thread-safe, because if it cannot be modified, then it cannot be corrupted.
What you must realize is that i++
is not simply a method call on some i
value; it is an assignment of i
to a new value. This operation -- assigning i
to a new incremented value -- is not thread-safe in the sense that two threads might both execute this code concurrently and you can end up with a new value of i
that is only 1 greater than the previous value. That is what Interlocked.Increment
is for. But the MSDN documentation is not lying to you; the internal state of i
is no way compromised by multithreaded access.