1

Sorry for the title of the post, don't know how to express it better..

I have an object unit which I save to the filesystem using MemoryStream and BinaryFormatter.

Now I have to run an NUNIT test that checks if both objects car and carloadedFromDisk are equal. This test fails, because it looks like they have different references on the heap.

Is it possible to have the deserialized object carloadedFromDisk to point to the existing reference of object car? What can I do to make the test pass?

Example:

var car = new Car("Audi");
var unit = new Unit("GoldSmith", car);

unit.save();
var carloadedFromDisk = Car.get(carId); // deserialized

Assert.AreEqual(unit.Car, carloadedFromDisk); // <-- fails
Legends
  • 21,202
  • 16
  • 97
  • 123

1 Answers1

1

Is it possible to have the deserialized object carloadedFromDisk to point to the existing reference of object car?

It is not possible. The new instance is created during deserialization. Even if you could pass existing instance to be filled by deserializer, then you would end up with single car instance compared to itself (always true).

Now I have to run an NUNIT test that checks if both objects car and carloadedFromDisk are equal. This test fails, because it looks like they have different references on the heap.

Instead of comparing references, you should compare values. Implement Equals and GetHashCode methods in your Car class so that fields of Car instances would be used for comparison and hash generation. Equals will be called by Assert.AreEqual assertion. E.g. if your Car has two properties:

public int Id { get; set; }
public string Name { get; set; }

public override bool Equals(object obj) 
{
   if (obj == null || GetType() != obj.GetType()) 
      return false;

   Car other = (Car)obj;
   return (Id == other.Id) && (Name == other.Name);
}

public override int GetHashCode() 
{
   unchecked 
   {
       int hash = 19;
       hash = hash * 23 + Id;
       hash = hash * 23 + Name == null ? 0 : Name.GetHashCode();
       return hash;
   }
}

Further reading: Implementing the Equals Method

Sergey Berezovskiy
  • 232,247
  • 41
  • 429
  • 459
  • Why do you use 19 as an initial value for the hash and why do you use 23 to multiply the hash, by accident? Thanks for the quick reply! – Legends Jul 07 '17 at 23:09
  • 1
    @Legends that's prime numbers - and purpose is to get good hash code distribution to avoid all items going into same bucket(s) of dictionary or other hash collection. Though people say it's [better to use big prime numbers](https://stackoverflow.com/questions/263400/what-is-the-best-algorithm-for-an-overridden-system-object-gethashcode) – Sergey Berezovskiy Jul 07 '17 at 23:25