1

I have some code that allows me to compare to Entity Framework entities.

However, I've noticed that it sometimes returns false (not matched) when it is in fact true (from a logical perspective).

It fails because of the HashSets - they always return false when compared. HashSets are typically navigation links to other entities which I don't need to compare.

Are there any modifications I can make to this code to make it work correctly?

namespace Common.Helper
{
    public sealed class PocoHelper<TPOCO> : IEqualityComparer<TPOCO> where TPOCO : class
    {
        public bool Equals(TPOCO poco1, TPOCO poco2)
        {
            var t = typeof(TPOCO);

            if (poco1.IsNotNull() && poco2.IsNotNull())
            {
                bool areSame = true;

                foreach(var property in typeof(TPOCO).GetPublicProperties())
                {
                    object v1 = property.GetValue(poco1, null);
                    object v2 = property.GetValue(poco2, null);

                    if (!object.Equals(v1, v2))
                    {
                        areSame = false;
                        break;
                    }
                };

                return areSame;
            }

            return poco1 == poco2;
        }   

        public int GetHashCode(TPOCO poco)
        {
            int hash = 0;
            foreach(var property in typeof(TPOCO).GetPublicProperties())
            {
                object val = property.GetValue(poco, null);
                hash += (val == null ? 0 : val.GetHashCode());
            };
            return hash;
        }  
    } 
}
dotnetnoob
  • 10,783
  • 20
  • 57
  • 103

1 Answers1

-1

You should return false when any or both of the objects you are comparing is null.

        if (poco1.IsNotNull() && poco2.IsNotNull())
        {
            bool areSame = true;

            foreach(var property in typeof(TPOCO).GetPublicProperties())
            {
                object v1 = property.GetValue(poco1, null);
                object v2 = property.GetValue(poco2, null);

                if (!object.Equals(v1, v2))
                {
                    areSame = false;
                    break;
                }
            };

            return areSame;
        } else {
            return false;
        }

Because as given on msdn your "==" would return true

    // Returns true.
    Console.WriteLine("null == null is {0}", null == null);

You can view at http://msdn.microsoft.com/en-gb/library/edakx9da.aspx

Regarding hashsets: The object type of your HashSet doesn't have to implement IEqualityComparer but instead just has to override Object.GetHashCode() and Object.Equals(Object obj). You can see full post at How does HashSet compare elements for equality?

Community
  • 1
  • 1
Softec
  • 1,087
  • 11
  • 14