我有一个Vector类,我正在测试以下单元测试(使用nUnit)。
1 Vector test1 = new Vector(new double[] { 6, 3, 4, 5 });
2 Vector test2 = test1;
3 Assert.AreEqual(test1, test2, "Reference test");
4 test2 = new Vector(new double[] { 3, 3, 4, 5 });
5 Assert.AreEqual(test1, test2, "Reference test");
第3行的第一次测试通过,但第5行的第二次测试失败。 test2也不应该指向与test1相同的内存,因为我在第2行做了赋值语句吗?我的Vector被定义为一个类,因此它是一个引用类型。另一方面,以下测试通过:
1 Vector test1 = new Vector(new double[] { 6, 3, 4, 5 });
2 Vector test2 = test1;
3 Assert.AreEqual(test1, test2, "Reference test");
4 test2[1] = 4;
5 Assert.AreEqual(test1, test2, "Reference test");
这是否意味着,当我使用new运算符定义新对象时,旧的赋值不再有效?任何其他(或正确 - 如果我错了)解释?
答案 0 :(得分:4)
该行
test2 = new Vector(new double[] { 3, 3, 4, 5 });
在堆上创建Vector
的新实例,并将其地址分配给test2
变量。在此之后,test2
将指向一个新的,完全不同的对象。
相反,行
test2[1] = 4;
不会更改test2
变量本身(它是对堆上某个对象的引用)。相反,它正在改变它指向的对象。 test2
仍然指向堆上的相同位置。
总结一下,在前者中,您正在更改引用,而在后者中,您正在更改引用。
答案 1 :(得分:1)
分配变量时:
test2 = new Vector(new double[] { 3, 3, 4, 5 });
您正在将test2的值更改为赋值运算符右侧返回的新引用。当然,这里返回的引用与test1
中引用的引用不同,因为它是被调用的构造函数的单独情况,并且引用不可能是相同的,因为Vector是用不同的参数构造的。
答案 2 :(得分:0)
是的,当您使用new运算符定义新对象时,旧分配不再有效。
你的矢量是一种参考类型,但是当你说test2 =你说的是“现在test2指向别的东西”时。
顺便说一句,如果你想要两个具有相同内部值的不同Vector对象被认为是相等的,你可以通过在Vector类上实现IEquatable来实现它,但这是另一个问题......
答案 3 :(得分:0)
Equals
比较值以查看它们是否匹配,而如果您想比较参考,则需要使用ReferenceEquals
。
答案 4 :(得分:0)
Vector test1 = new Vector(new double[] { 6, 3, 4, 5 });
正在创建两个对象,即它自己的向量,以及对它的引用。
想象一下,您有一个页面上的项目列表。
使用new Vector
时,您可以在包含矢量的页面上有效地写一个新行。
物件
您还有一个引用列表(Vector test1 = new Vector),它可以引用第一页,并且(test2 = test1)
参考
当你说'test2 = new Vector {5,4,3,2,1}时,你会在第一页上找到一个新的矢量对象,并改变test2引用的向量。
物件
参考
在你的第二个例子中,test1和test2仍然指向同一个对象,这就是测试通过的原因。