2

我有一个 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 行的第二个测试失败。既然我在第 2 行做了赋值语句,那么 test2 不应该也指向与 test1 相同的内存吗?我的 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 运算符定义新对象时,旧分配不再有效?任何其他(或正确的 - 如果我错了)解释?

4

5 回答 5

4

线

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

在堆上创建一个新实例Vector并将其地址分配给test2变量。test2之后将指向一个新的、完全不同的对象。

相比之下,线

test2[1] = 4;

不会更改test2变量本身(这是对堆上某个对象的引用)。相反,它正在改变它指向的对象。test2仍然指的是堆上的相同位置。

总而言之,在前者中,您正在更改引用,而在后者中,您正在更改所指对象

于 2010-01-07T05:46:04.233 回答
1

当您分配如下变量时:

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

您正在将 test2 的值更改为赋值运算符右侧返回的新引用。当然,这里返回的引用与 中的引用不同test1,因为它是调用构造函数的单独情况,并且引用不可能相同,因为 Vector 是用不同的参数构造的。

于 2010-01-07T05:46:37.180 回答
0

是的,当您使用 new 运算符定义新对象时,旧的分配不再有效。

您的向量是参考类型,但是当您说 test2 = something 时,您是在说“现在 test2 指向其他东西”。

顺便说一句,如果您希望将具有相同内部值的两个不同 Vector 对象视为相等,则可以通过在 Vector 类上实现 IEquatable 来实现,但这是另一个问题...

于 2010-01-07T05:47:05.807 回答
0

Equals比较值以查看它们是否匹配,而如果要比较引用,则需要使用ReferenceEquals.

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

于 2010-01-07T05:53:03.610 回答
0
Vector test1 = new Vector(new double[] { 6, 3, 4, 5 });

正在创建两个对象,向量它的自身和对它的引用。

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

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

对象

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

您还有一个引用第一页的引用列表 (Vector test1 = new Vector) 和 (test2 = test1)

参考

  1. 测试1-> 1
  2. 测试2-> 1

当您说 'test2 = new Vector {5,4,3,2,1} 时,您最终会在第一页上看到一个新的向量对象,并更改 test2 所指的向量。

对象

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

参考

  1. 测试1-> 1
  2. 测试2 -> 2

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

于 2010-01-07T06:04:15.760 回答