下面的代码有一个运行时问题,即由赋值后缀/前缀增量语句产生的意外引用,如下面的代码所示。也有人可以建议我用一种方法来对待对象作为值类型在c#中建议下面如果有的话?
我相信这段代码有很好的文档,注释阐明了每个重要的状态。关于代码的澄清或手头的问题,请随时提出任何问题。
提前感谢。
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'
基本上,您误解了这一行的工作原理:
Test obj2 = ++obj;
如果你把你的操作符当作一个方法来使用,那就像是在说:
obj = Test.operator++(obj);
obj2 = obj;
所以,是的,你最终得到obj
和obj2
是相同的参考。++obj
的结果是obj
后应用++
运算符的值,但++
运算符也影响obj
的值。
如果使用
Test obj2 = obj++;
那就等于:
Test tmp = obj;
obj = Test.operator++(obj);
obj2 = tmp;
此时,obj2
的值为原对象,obj
的值为新创建的对象,且x
的值更高。
关于Console.WriteLine
结果的其余问题实际上是因为您没有覆盖ToString()
。
您正在尝试调整声明为class
的类型以表现为struct
。这对我来说没有任何意义。如果您将class Test
更改为struct Test
,删除无参数构造函数并覆盖.ToString
方法,则所有问题都解决了。
首先,每次递增(Post或Pre)时都创建了一个新的Test实例。所以当你输入这行:
Test obj2 = ++obj;
就好像你在写:
obj = new Test(obj.x + 1);
Test obj2 = obj;
第二,对于打印问题,只需重写ToString:
public override string ToString()
{
return x.ToString();
}
如果您阅读了您提供的指向已删除答案的链接,则:
Test obj2 = ++obj;
被翻译成
temp = operator++(obj);
obj = temp;
obj2 = temp;
这意味着它们有相同的引用