views:

123

answers:

5

I have a Vector class, and I was testing the following unit test (using 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");

The first test in line 3 passes, but the second test in line 5 fails. Shouldn't test2 also point to the same memory as test1, since I did the assignment statement in line 2? My Vector is defined as a class, so it is a reference type. On the other hand, the following tests pass:

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");

Does that mean that, when I use the new operator to define a new object, old assignments are no longer valid? Any other (or correct - if I am wrong) explanation?

+4  A: 

The line

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

creates a new instance of Vector on the heap and assigns its address to the test2 variable. test2 will point to a new, completely distinct object after that.

In contrast, the line

test2[1] = 4;

does not change the test2 variable itself (which is a reference to some object on the heap). Rather, it's changing the object it points to. test2 still refers to the same location on the heap.

To summarize, in the former, you are changing the reference while in the latter, you are altering the referent.

Mehrdad Afshari
After test2[1] = 4, you will see that test1[1] will also be equal to 4.
Tarydon
It should be pointed out that test2[1] = 4; will also cause test1[1] to change, since they're both pointing at the same object. So of course they're still equal.
Erik
+1  A: 

When you assign a variable like:

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

You are changing the value of test2 to be the new reference returned by the right hand side of the assignment operator. Of course the reference returned here is different than the one in test1, because it is a separate case of the constructor being called, and the references could not possibly be the same, as the Vector is being constructed with different arguments.

avpx
A: 

Yes, when you use the new operator to define a new object, old assignments are no longer valid.

Your vector IS a reference type, but when you say test2 = something you are saying "now test2 points to something else".

As an aside, if you want two different Vector objects with the same internal values to be considered equal, you can get that by implementing IEquatable on your Vector class, but that's another question...

Benjol
A: 

Equals compares the values to see if they match, whereas if you want to compare references you need to use ReferenceEquals.

Check out http://msdn.microsoft.com/en-us/library/dd183752.aspx

Will
A: 

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

Is creating two objects, the vector its self, and the reference to it.

Imagin you have a list of items on a page.

When you use new Vector you effectively write a new line on the page which contains the vector.

Objects

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

You also have a list of references (Vector test1 = new Vector) which referance the first page, and (test2 = test1)

References

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

when you say 'test2 = new Vector {5,4,3,2,1} you then end up with a new vector object on the first page, and change which vector test2 is referring to.

Objects

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

References

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

In your second example both test1 and test2 are still pointing to the same object, which is why the test passes.

Courtney de Lautour