C#中的前缀和后缀运算符重载

时间:2016-08-30 10:03:41

标签: c# oop postfix-operator prefix-operator

以下代码存在运行时问题,通过分配后缀/前缀增量语句进行意外引用,如下面的代码所示。也有人可以建议我在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'

3 个答案:

答案 0 :(得分:4)

基本上,你误解了这条线是如何工作的:

Test obj2 = ++obj;

如果您考虑使用运算符作为方法,那就像是说:

obj = Test.operator++(obj);
obj2 = obj;

所以是的,您最终得到的objobj2是相同的参考。 <{1}}的结果是应用++obj运算符后obj 的值,但++运算符会影响++的值也是。

如果您使用

obj

那相当于:

Test obj2 = obj++;

此时,Test tmp = obj; obj = Test.operator++(obj); obj2 = tmp; 的值将引用原始对象,obj2的值将引用具有更高obj值的新创建的对象。 / p>

关于x结果的其余问题实际上是因为您没有覆盖Console.WriteLine

答案 1 :(得分:1)

如果您阅读了为删除的答案提供的link,那么:

Package: mypackage
Type: Package
...
Description: Only one too long line which goes over the right border of the pdf
License: GPL-3  
...

翻译为

Test obj2 = ++obj;

这意味着它们具有相同的参考。

答案 2 :(得分:1)

您尝试调整声明为ToString()的类型,使其表现为class。这对我没有任何意义。如果您将struct更改为class Test,请删除无参数构造函数并覆盖struct Test方法,所有问题都将消失。

首先,每次增加(Post或Pre)时,您都会创建一个新的Test实例。所以当你点击这一行时:

.ToString

好像你在写:

Test obj2 = ++obj;

其次,对于打印问题,只需覆盖ToString:

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