Declaring Increment and Decrement Operators


Declaring Increment and Decrement Operators

C# allows you to declare your own version of the increment (++) and decrement (––) operators. The usual rules apply when declaring these operators; they must be public, they must be static, and they must be unary. Here is the increment operator for the Hour struct:

struct Hour {     ...     public static Hour operator++ (Hour arg)     {         arg.value++;         return arg;     }     ...     private int value; }

The increment and decrement operators are unique in that they can be used in prefix and postfix forms. C# cleverly uses the same single operator for both the prefix and postfix versions. The result of a postfix expression is the value of the operand before the expression takes place. In other words, the compiler effectively converts this:

Hour now = new Hour(9); Hour postfix = now++;

Into this:

Hour now = new Hour(9); Hour postfix = now; now = Hour.operator++(now); // pseudocode, not valid C#

The result of a prefix expression is the return value of the operator. The C# compiler effectively converts this:

Hour now = new Hour(9); Hour prefix = ++now;

Into this:

Hour now = new Hour(9); now = Hour.operator++(now); // pseudocode, not valid C# Hour prefix = now;

This equivalence means that the return type of the increment and decrement operators must be the same as the parameter type.

Operators in Structs and Classes

It is important to realize that the implementation of the increment operator in the Hour struct works only because Hour is a struct. If you change Hour into a class but leave the implementation of its increment operator unchanged, you will find that the postfix translation won't give the correct answer. If you remember that a class is a reference type and revisit the compiler translations explained previously, you can see why this occurs:

Hour now = new Hour(9); Hour postfix = now; now = Hour.operator++(now); // pseudocode, not valid C#

If Hour is a class, the assignment statement postfix = now makes the variable postfix refer to the same object as now. Updating now automatically updates postfix! If Hour is a struct, the assignment statement makes a copy of now in postfix, and any changes to now leave postfix unchanged, which is what we want.

The correct implementation of the increment operator when Hour is a class is as follows:

class Hour {     public Hour(int initialValue)     {         this.value = initialValue;     }     ...     public static Hour operator++(Hour arg)     {         return new Hour(arg.value + 1);     }     ...     private int value; }

Notice that operator++ now creates a new object based on the data in the original. The data in the new object is incremented but the data in the original is left unchanged. Although this works, the compiler translation of the increment operator results in a new object being created each time it is used. This can be expensive in terms of memory use and garbage collection overhead. Therefore, it is recommended that you limit operator overloads when you define classes.




Microsoft Visual C# 2005 Step by Step
Microsoft® Visual C#® 2005 Step by Step (Step By Step (Microsoft))
ISBN: B002CKYPPM
EAN: N/A
Year: 2005
Pages: 183
Authors: John Sharp

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net