I have the following class:
public class Foo
{
public Guid Id { get; set; }
public string Bar { get; set; }
public DateTime Baz { get; set; }
}
And I want to test it for equality in a Dictionary like so:
var dict = new Dictionary<Guid, Foo>();
// Add some foos...
if (dict.ContainsValue(myFoo))
{
// Do something...
}
Where ContainsValue should return true for Foos where the Bar and Baz properties are equal to one already in the dictionary.
The ContainsValue documentation states that the default EqualityComparer is used. This suggests that I can implement the IEquatable interface and override the default Equals implementation like so:
public override bool Equals(Foo obj)
{
return obj != null &&
Id.Equals(obj.Id) &&
Bar == obj.Bar &&
Baz == obj.Baz;
}
This blog post from MSDN suggests that when implementing IEquatable, one must also override the Equals(object) and GetHashCode() functions.
However, if I were to use the same Equality logic for the Equals and GetHashCode functions, the object's hashcode would be based on mutable fields which is recommended against in this StackOverflow answer.
So therefore, my question:
How should we define equality logic for mutable objects in cases like the one shown above whilst avoiding the problems inherent in basing an object's hashcode on mutable values?