In my current project, I am trying to compare two lists of objects, figuring out whether the same objects were added, deleted, changed, or remained.
I am using IEnumerable.Except for this as follows:
Dim newOnes = current.Except(previous, equalityComparer).ToList Dim removedOnes = previous.Except(current, equalityComparer).ToList() Dim existingOnes = current.Except(newOnes, equalityComparer).ToList Dim changedOnes = existingOnes.Except(previous, changedComparer).ToList() Dim unchangedOnes = existingOnes.Except(changedOnes, equalityComparer).ToList()
For this, I have to implement IEqualityComparers.
After finding out whether a pair of objects has changed in the property values (changedOnes), you need to write "changedComparer", which is IEqualityComparer, which checks non-identification fields (for example, member collections).
Since the Except method apparently checks the GetHashCode first and doesn't go to the Equals method if the hashes are equal, my setup is falling apart.
I am currently solving this as follows:
Public Overloads Function GetHashCode(obj As Family) As Integer Implements IEqualityComparer(Of Family).GetHashCode Dim hashCode As Long = 17 If obj.ClientCode IsNot Nothing Then hashCode = CInt(((hashCode * 397) Xor obj.ClientCode.GetHashCode()) Mod Integer.MaxValue) ' SNIP a bunch more property fields If obj.Members IsNot Nothing Then hashCode = CInt(((hashCode * 397) Xor obj.Members.GetHashCode()) Mod Integer.MaxValue) Return CInt(hashCode Mod Integer.MaxValue) End Function
Adding a member list hash always returns a different hash, as it validates the instance, not the contents. This works for now, but off course removes all the benefits of having a hash.
UPDATE
What I'm looking for is not the best Equals method, but I questioned my entire methodology (maybe there is something OOTB, I should use a different interface). Otherwise, how can I get a good GetHashcode when my collection of properties needs to be taken into account?