C# 中的前缀和后缀运算符重载
Prefix and Postfix operator overloading in C#
以下代码存在运行时问题,通过分配 postfix/prefix 增量语句进行意外引用,如下面的代码所示。还有谁能给我建议一种在 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'
如果您阅读了您提供给已删除答案的 link,那么:
Test obj2 = ++obj;
翻译成
temp = operator++(obj);
obj = temp;
obj2 = temp;
这意味着它们具有相同的引用。
基本上,您误解了这条线的工作原理:
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();
}
以下代码存在运行时问题,通过分配 postfix/prefix 增量语句进行意外引用,如下面的代码所示。还有谁能给我建议一种在 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'
如果您阅读了您提供给已删除答案的 link,那么:
Test obj2 = ++obj;
翻译成
temp = operator++(obj);
obj = temp;
obj2 = temp;
这意味着它们具有相同的引用。
基本上,您误解了这条线的工作原理:
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();
}