Nic*_*ick 2 c# operator-overloading
大多数消息来源说,在c#中重载++和 - 运算符导致一次性重载postfix和prefix.但看起来他们的行为仍然不同.
class Counter
{
public Counter(int v = 0)
{
this.v = v;
}
public Counter(Counter c)
{
v = c.v;
}
public int GetValue() { return v; }
public static Counter operator ++(Counter c)
{
c.v++;
return new Counter(c);
}
private int v;
}
class Program
{
public static void Main()
{
Counter c1 = new Counter(1);
Counter c2 = c1++;
Counter c3 = ++c1;
c3++;
System.Console.WriteLine("c1 = {0}", c1.GetValue());
System.Console.WriteLine("c2 = {0}", c2.GetValue());
System.Console.WriteLine("c3 = {0}", c3.GetValue());
}
}
Run Code Online (Sandbox Code Playgroud)
奇妙的是,虽然重载operator ++返回原始类的副本,但在此示例中c1并c3成为对同一对象的引用,同时c2指向不同的(c1=4, c2=2, c3=4此处).改变Counter c3 = ++c1;为Counter c3 = c1++;输出c1=3, c2=2, c3=4.
那么,后缀和前缀增量/减量之间的确切区别是什么以及它如何影响重载?这些运算符对类和原始类型的作用是否相同?
Eri*_*ert 11
这是在C#中实现递增和递减的错误方法.如果你做错了,你会得到疯狂的结果; 你做错了,你得到了疯狂的结果,所以系统工作.:-)
巧合的是,我上周写了一篇关于这个主题的文章:
http://ericlippert.com/2013/09/25/bug-guys-meets-math-from-scratch/
正如评论者dtb指出的那样,正确的实施是:
public static Counter operator ++(Counter c)
{
return new Counter(c.v + 1);
}
Run Code Online (Sandbox Code Playgroud)
在C#中,increment运算符不能改变其参数.相反,它必须只计算递增的值并返回它,而不会产生任何副作用.改变变量的副作用将由编译器处理.
有了这个正确的实现,您的程序现在是这样的:
Counter c1 = new Counter(1);
Run Code Online (Sandbox Code Playgroud)
现在调用c1引用的对象W.W.v是1.
Counter c2 = c1++;
Run Code Online (Sandbox Code Playgroud)
这有以下语义:
temp = c1
c1 = operator++(c1) // create object X, set X.v to 2
c2 = temp
Run Code Online (Sandbox Code Playgroud)
所以c1现在指的是X,并且c2指的是W. W.v是1并且X.v是2.
Counter c3 = ++c1;
Run Code Online (Sandbox Code Playgroud)
这有语义
temp = operator++(c1) // Create object Y, set Y.v to 3
c1 = temp
c3 = temp
Run Code Online (Sandbox Code Playgroud)
所以c1和c3现在都引用了对象Y,并且Y.v是3.
c3++;
Run Code Online (Sandbox Code Playgroud)
这有语义
c3 = operator++(c3) // Create object Z, set Z.v to 4
Run Code Online (Sandbox Code Playgroud)
所以当烟雾全部清除时:
c1.v = 3 (Y)
c2.v = 1 (W)
c3.v = 4 (Z)
Run Code Online (Sandbox Code Playgroud)
并且X是孤儿.
这应该给出与您所拥有的完全相同的结果c1,c2以及c3正常的整数.
| 归档时间: |
|
| 查看次数: |
2113 次 |
| 最近记录: |