hecate hecate - 3 months ago 20
C# Question

Prefix and Postfix operator overloading in C#

The following code has a runtime issue with unexpected references made by assignment of postfix/prefix increment statement as shown in the code bellow. Also can anyone please suggest me with a way to treat objects as value types in C# as suggested bellow if any?

I believe that the code is well documented with comments clarifying each important state. Feel free to ask any questions regarding clarification of code or the problem at hand.

Thanks in advance.

class Test {

public int x;

public Test(int x) { this.x=x; }
public Test() { x=0; }

static public Test operator++(Test obj) {
return new Test(obj.x+1);
}
}

// In implementing module
// Prefix/Postfix operator test for inbuilt (scalar) datatype 'int'
int x=2;
int y=++x; // 'y' and 'x' now both have value '3'
Console.WriteLine(x++); // Displays '3'
Console.WriteLine(++x); // Displays '5'
Console.WriteLine(ReferenceEquals(x,y)); // Displays 'False'


// Prefix/Postfix operator test of class type 'Test'
Test obj=new Test();
obj.x=1;
Console.WriteLine(obj++); // Must have displayed '1', displays the object type (Test.Test)
Console.WriteLine(++obj); // Must have displayed '3', again displays the object type (Test.Test)
Console.WriteLine(obj.x); // Displays '3' (as expected)

Test obj2=++obj; // Must have the value '4' and must NOT be the reference of obj
// Alternative solution to the above statement can be : 'Test obj2=new Test(++obj);' but isn't there a way to create a new value type in C# by the above statement ??!! (In C++, it can be acheived by overloading the '=' operator but C# doesn't allow it)
Console.WriteLine(obj2.x); // Displays '4' (as expected)
Console.WriteLine(ReferenceEquals(obj,obj2)); // Must display 'False' but displays 'True' showing that 'obj2' is the reference of 'obj'

Answer

You're trying to adjust a type that is declared as class to behave as a struct. This doesn't make any sense for me. If you change class Test to struct Test, remove the parameterless constructor and override the .ToString method, all the problems are gone.

First, You're creating a new instance of Test each time you increment (Post or Pre). So when you hit this line:

Test obj2 = ++obj;

As if you're writing:

obj = new Test(obj.x + 1);
Test obj2 = obj;

Second and as for the printing issue, just override the ToString:

public override string ToString()
{
    return x.ToString();
}