Question

I have a case where two objects can be compared many different ways for equality. For example:

public class HeightComparer : IEqualityComparer<Person> {
   public bool Equals(Person x, Person y) {
       return x.Height.Equals(y.Height);
   }

   public int GetHashCode(Person obj) {
       return obj.Height;
   }
}

And I use these comparers in Dictionary<Person,Person>(IEqualityComparer<Person>) for various methods. How would you make a comparer that guarantees each person is unique? I came up with the following, but it runs slow since the GetHashCode() method often returns the same value.

public class NullPersonComparer : IEqualityComparer<Person> {
   public bool Equals(Person x, Person y) {
       return false; // always unequal
   }

   public int GetHashCode(Person obj) {
       return obj.GetHashCode();
   }
}

I could return the same value of 0 from GetHashCode(Person obj) but it still is slow populating the dictionary.

Edit

Here is a use case:

 Dictionary<Person, Person> people = new Dictionary<Person, Person>(comparer);
 foreach (string name in Names)
 {
     Person person= new Person(name);
     Person realPerson;
     if (people.TryGetValue(person, out realPerson))
     {
         realPerson.AddName(name);
     }
     else
     {
         people.Add(person, person);
     }
  }
Was it helpful?

Solution

If the type has not overridden the Equals or GetHashCode methods then their default implementations, from object, do what you want, namely provide equality based on their identity, rather than their value. You can use EqualityComparer<Person>.Default to get an IEqualityComparer that uses those semantics if you want.

If the Equals method has been overridden to provide some sort of value semantics, but you don't want that, you want identity semantics, then you can use object.ReferenceEquals in your own implementation:

public class IdentityComparer<T> : IEqualityComparer<T>
{
    public bool Equals(T x, T y)
    {
        return object.ReferenceEquals(x, y);
    }

    public int GetHashCode(T obj)
    {
        return System.Runtime.CompilerServices.RuntimeHelpers.GetHashCode(obj);
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top