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'
Basically, you've misunderstood how this line works:
Test obj2 = ++obj;
If you think of using your operator as a method, that's like saying:
obj = Test.operator++(obj);
obj2 = obj;
So yes, you end up with obj
and obj2
being the same reference. The result of ++obj
is the value of obj
after applying the ++
operator, but that ++
operator affects the value of obj
too.
If you use
Test obj2 = obj++;
then that's equivalent to:
Test tmp = obj;
obj = Test.operator++(obj);
obj2 = tmp;
At that point, the value of obj2
will refer to the original object, and the vlaue of obj
will refer to the newly-created object with a higher x
value.
The rest of your question around the result of Console.WriteLine
is really because you haven't overridden ToString()
.
See more on this question at Stackoverflow