Entity equality does not work in all cases

May 28, 2009 at 10:11 PM
Edited May 28, 2009 at 10:17 PM

Hi Tim,

I have come across a very subtle bug in the EntityBase == operator overload method in the following statement:

if (base1.Key != base2.Key)

This does not work if the base1.Key and base2.Key properties don't reference the same Guid object, but have the same value.  The statement does work if both Key properties reference the same Guid object.  The fix for this bug is to replace the statement with this one:

if (base1.Key.Equals(base2.Key))

This second statement works fine in all cases.  The reason for this has to do with the fact that the == and != operator overloads are not virtual whereas the Equals method is virtual.  So, what happens in the first statement is that the != operator overload for the System.Object class is called and not the overload defined in the Guid class, since the Key property is declared as type object.  This causes a reference comparison and not a value comparison.  A value comparison is what is needed for this operator overload to work as needed.  The second statement will cause the Equals method of the Guid struct to be called and not the one defined for the System.Object class, since it is virtual, and the correct value comparison between the two  Guids is done, instead of a reference comparison.

Here is a unit test that demonstrates the issue:

        public void EntitiesAreEqualIfDifferentEntityAndKeyObjectsButSameKeyValue()

        {

            EntityBase entity1 = new EntityBase();

            Guid id2 = new Guid(entity1.Key.ToString());

            EntityBase entity2 = new EntityBase(id2);

            Assert.AreEqual(entity1.Key, entity2.Key);

            Assert.AreEqual(entity1, entity2);

            Assert.IsTrue(entity1.Equals(entity2));

            Assert.IsTrue(entity1 == entity2);

            Assert.IsFalse(entity1 != entity2);

        }

This unit test will fail on the second Assert.  When I change the EntityBase == operator overload method with the new statement above, this unit test passes.

Jul 8, 2009 at 11:25 PM

Nice catch...  I haven't run into an issue with it, yet, but I've modified my local unit tests to catch this, too.

Nov 24, 2010 at 2:48 AM

Thanks! It's really a good catch!

May 12, 2011 at 6:17 AM
This discussion has been copied to a work item. Click here to go to the work item and continue the discussion.