views:

177

answers:

2

I've got some code which I use to loop through the properties of certain objects and compare the property values, which looks somewhat like this:

public static bool AreObjectPropertyValuesEqual(object a, object b)
{

 if (a.GetType() != b.GetType())
  throw new ArgumentException("The objects must be of the same type.");

 Type type = a.GetType();

 foreach (PropertyInfo propInfo in type.GetProperties())
 {
  if (propInfo.GetValue(a, null) != propInfo.GetValue(b, null))
  {
   return false;
  }
 }
 return true;
}

Now for the weird behaviour. I've created a class called PurchaseOrder with a couple of properties, all of which are simple datatypes (strings, ints, etc.). I create one instance in my Unit-Test code and another one is created by my DataModel, fetching the data from a database (MySql, I'm using the MySqlConnector).

Eventhough the debugger shows me, that the property values are identical, the comparison in the code above fails.

That is: my object A created in the UnitTest has an Amount property value of 10. The object B retrieved from my Repository has an Amount property value of 10. Comparison fails! If I change the code to

if (propInfo.GetValue(a, null).ToString() != propInfo.GetValue(b, null).ToString())
{
 ...
}

everything works as I would expect. The comparison doesn't fail as well if I create PurchaseOrder instances directly in the UnitTest.

I'd be very thankful for any anwers. Have a good day!

+1  A: 

The reason for the failure is that the equality test that gets applied above is a reference equality test. Since the two objects returned by propInfo.GetValue(foo, null), though equal by their own definitions, are separate objects, their references are different, and thus the equality fails.

Marcus Griep
Exactly. I could have thought about that sooner. :) Thanks for your reply!
Matthias
+3  A: 

PropertyInfo.GetValue returns an object, and your unit test is doing an == reference comparison. Try this instead:

if (!propInfo.GetValue(a, null).Equals(propInfo.GetValue(b, null)))

You may want to replace null with something more sensible...

Alternatively, you could try:

if ((int?)propInfo.GetValue(a, null) != (int?)propInfo.GetValue(b, null))

(or whatever simple type you have if it's not an int) which forces the value type == behaviour.

David M
Works perfectly, thank a lot. null is in there, because I didn't want to make the code sample overly complicated.
Matthias