Question

I have POCOs from a SQL Server database that have an identity ID field. I would like to implement IEquatable so I can check if they're the same record, use .Contains() on List<T> etc.

Assuming I will never need to compare unsaved instances, is it sufficient to just implement using:

    public bool Equals(MyClass other)
    {
        return this.ID == other.ID;
    }

    public override int GetHashCode()
    {
        return this.ID;
    }

I'm about to do this, but just wanted to check that's fine, as I'm not 100% sure what GetHashCode has to do with it, or if there are any other considerations (such as the "unsaved instance" one, which I can discard) that I'm not aware of.

Was it helpful?

Solution

You need to override GetHashCode() whenever you override Equals() (which you should also do when you implement IEquatable<T>) so that classes that rely on it, such as Dictionary<TKey, TValue>, can handle it correctly. It's one of those inner details that annoyingly leaks out. More information.

As for whether comparing your IDs is sufficient for determining equality, if you're absolutely sure that two entities with the same ID should be considered equivalent under all circumstances, then go for it. That's a question only the requirements of your application can answer. I've done it quite a few times myself, almost always with read-only entities.

I would implement it this way:

// IEquatable<MyClass> implementation
public bool Equals(MyClass other) 
{
  if (other == null) 
  {
    return false;
  }

  return this.ID == other.ID;
}

// Override of default Object.Equals()
public override bool Equals(object other) 
{
  return this.Equals(other as MyClass);
}

public override int GetHashCode()
{
  // Call ID.GetHashCode() because ID may not always be int,
  // and the ID type might have a more useful implementation
  // of GetHashCode() to offer.
  return this.ID.GetHashCode(); 
}

You should probably also override the == and != operators in this case. You can always use Object.ReferenceEquals() if you want to distinguish between two distinct references with the same ID.

OTHER TIPS

If, by your businessrules, your objects are equal to each other when their ID's are equal, than you are doing just fine!

The hashcode of an object state that every object with a different state, should return a different hashcode. This hashcode is not unique, but we can try to make them as different as possible. Just check out the hashcode of strings "Hello".GetHashCode() and "Goodbye".GetHashCode().

HashCode is used in some collections, like System.Collections.Generic.Dictionary<K,V> and System.Collections.Generic.HashSet<T>. By using this hashcode, those dictionary can search and find an item very fast (almost an O(1)-operation) by using this 'unique' hashcode. Calculate this hashcode by using the hashcodes of the field(s) of your entity.

If you implement IEquatable<T>.Equals, also override Equals(object).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top