Home Dashboard Directory Help

C# postdecrement overloads by A. de Winkel


 as By Design Help for as By Design

Sign in
to vote
Type: Suggestion
ID: 243943
Opened: 12/7/2006 1:05:52 AM
Access Restriction: Public


dear Reader.

I've posted this issue somewhere else, but currently still don't know how to implement postincrement and postdecrement operators in c#.

Using c/c++ it was possible to implement both post and pre incremental or decremental operators to get both ++X and X++ to operate as it should. Though these operations are simularly defined in c# I can't find c#-ways to implement a postincrement operator on my numeric classes, when used in postincremental way the result is still preincremental.
ie X=5; Y = X++; results in Y=6 instead of 5 (using int X and Y as example).

Thus simple question:
in C# can I make a distinction between post and pre incremental or decremental operators.
If so, there seem to be some omissions in the helpsystem. Iff not, might this omission be added in a future C# version.

"Postdecremental" assignment:
As a further operator issue, well known is the statement X -= Y to stand for X = X - Y and as such most usefull, however I find myself with many a line: X = Y - X. Thus would make perfect sense if thus could be written as X =- Y.
simular X =/ Y could stand for X = Y / X (as opposed to X /= Y, which is X = X / Y)
Note I know these two are but some (wild) ideas, which would add two entirely new usefull assingment operators.
Sign in to post a comment.
Posted by Microsoft on 2/8/2008 at 1:08 AM
Hey A. de Winkel,

In C#, when you override the ++ operator, you are implementing the pre-increment operation. C# then implements the post-increment operator for you, by saving the object as is, calling your pre-increment implementation, and then returning the saved object.

This works great for the built-in value types, as well as any value types you define yourself. For a value type, assigning the current value to save it causes the value to be copied. When you increment the underlying variable, the saved value is unchanged and you can return it as is to accomplish the postincrement.

For reference types, the same process happens (the object is saved, the pre-increment implementation is called, and the saved object is returned). But reference types are different than value types, in that when they are assigned, a reference to the object is copied, and not the object itself. This means even though you've "saved" the object, you have only copied a reference to it, and when you increment the underlying object, you are also incrementing the "copy".

This type of issue is common when dealing with values in reference types. The two standard solutions in C# are:

1. Use value types instead of reference types.
2. Make your reference type immutable, like string.

If you look at the string class, you will notice there are actually no methods that modify the string in-place, only methods that return you a new string that contains the changes you requested. If you implemented numeric in this fashion, always creating a new numeric object for every operation and returning that instead, you could successfully use reference types.

Unfortunately, an immutable type cannot have an operation that directly causes it to change, such as an increment operation, or you can get into extremely confusing situations. Consider the following code:

numeric a = new numeric(1);
numeric b = a;

If you are using reference types, a and b now point to the same object, and b will have the value 2. Every time you increment a, you are also incrementing b. This is not the behavior you will expect using your numeric object, and you will have many obscure bugs.

Because of the issue above, even if C# allowed you to implement a separate post-increment operator, the only way to get the meaningful behavior you want is still to make numeric into a value type instead of a reference type.

If you have any more questions, let us know!

Alex Turner
Program Manager
Visual C# Compiler
Posted by A. de Winkel on 10/16/2007 at 10:03 PM
If I read this correctly I need to wait till C# allows different syntaxis for post and prefix operators since to my knowledge class / value type implement the same and with a single syntax I can't return original / incremented value.
I was not looking for different syntaxis, the compiler should be able to differentiate the two into clr and perform pre / post assignment depending on pre / postfix operators.
This is independent of whether class / value type is used and one can have a single syntax!
Posted by Microsoft on 10/16/2007 at 3:35 PM
Thanks for responding,

While it is indeed very subtle, your repro behaves exactly as you asked it to, and the way the spec says it should. Your numeric type is a class, and variables of type numeric are references to objects. Your ++ implementation increments the contents of a numeric object and returns that same object.

So what does pre and post increment on a given numeric n do?
pre-increment increases the value inside n, and returns a reference to n
post-increment saves a reference to n, increments the value inside n and returns the saved reference to n

In both cases the same object n is returned. In both cases the value inside n is incremented. So of course the observable result is the same.

It is much easier to get the right semantics if you use value types.


Posted by A. de Winkel on 9/16/2007 at 9:50 PM
dear mr Hoban

Point is was and will be that currently the semantics IS different from predefined types, I expect that the postfixed change value after assignment as prefix change value before assignment. Since this is currently NOT the case (both behave like prefix) my numerical types don't work as they should (just like predefined types!)

See attached sample!
Posted by Microsoft on 9/14/2007 at 1:58 PM
Thanks for the additional information - and sorry for closing this out originally without sending you a comment.

The fact that you cannot override both prefix ++ and postfix ++ seperately is something that we won't change at the point in the C# langauage. Both syntaxes can be used, but they can't have different semantics for user defined types as they do for the predfined types.

Luke Hoban
Visual C# Compiler Program Manager

Posted by A. de Winkel on 1/30/2007 at 1:30 AM
to put it simpler see attachment.
how to let the numeric class (unchecked checkbox) behave like the normal integer sample (checked checkbox)

(excuse, better explanation got lost, but things are easy enough!)
Sign in to post a workaround.