参考问题:两个物体何时相等?

时间:2010-01-07 05:43:18

标签: c# .net variable-assignment reference-type

我有一个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运算符定义新对象时,旧的赋值不再有效?任何其他(或正确 - 如果我错了)解释?

5 个答案:

答案 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

查看http://msdn.microsoft.com/en-us/library/dd183752.aspx

答案 4 :(得分:0)

Vector test1 = new Vector(new double[] { 6, 3, 4, 5 });

正在创建两个对象,即它自己的向量,以及对它的引用。

想象一下,您有一个页面上的项目列表。

使用new Vector时,您可以在包含矢量的页面上有效地写一个新行。

物件

  1. {1,2,3,4,5}
  2. 您还有一个引用列表(Vector test1 = new Vector),它可以引用第一页,并且(test2 = test1)

    参考

    1. test1-> 1
    2. test2-> 1
    3. 当你说'test2 = new Vector {5,4,3,2,1}时,你会在第一页上找到一个新的矢量对象,并改变test2引用的向量。

      物件

      1. {1,2,3,4,5}
      2. {5,4,3,2,1}
      3. 参考

        1. test1 - > 1
        2. test2 - > 2

        3. 在你的第二个例子中,test1和test2仍然指向同一个对象,这就是测试通过的原因。