Search code examples
c#.netequals

What is the "best" canonical implementation of Equals() for reference types?


Implementing Equals() for reference types is harder than it seems. My current canonical implementation goes like this:

public bool Equals( MyClass obj )
{
  // If both refer to the same reference they are equal.
  if( ReferenceEquals( obj, this ) )
    return true;

  // If the other object is null they are not equal because in C# this cannot be null.
  if( ReferenceEquals( obj, null ) )
   return false;

   // Compare data to evaluate equality    
   return _data.Equals( obj._data );
}

public override bool Equals( object obj )
{
  // If both refer to the same reference they are equal.
  if( ReferenceEquals( obj, this ) )
    return true;

  // If the other object is null or is of a different types the objects are not equal. 
  if( ReferenceEquals( obj, null ) || obj.GetType() != GetType() )
    return false;

  // Use type-safe equality comparison
  return Equals( (MyClass)obj );
}

public override int GetHashCode()
{
  // Use data's hash code as our hashcode  
  return _data.GetHashCode();
}

I think that this covers all corner (inheritance and such) cases but I may be wrong. What do you guys think?


Solution

  • I wrote a fairly comprehensive guide to this a while back. For a start your equals implementations should be shared (i.e. the overload taking an object should pass through to the one taking a strongly typed object). Additionally you need to consider things such as your object should be immutable because of the need to override GetHashCode. More info here:

    http://gregbeech.com/blog/implementing-object-equality-in-dotnet