IEquatable

Can be used to determine equality of class instances.

1
2
3
4
var obj1 = new Foo();
var obj2 = new Foo();

obj1.Equals(obj2) // will return false as the memory reference is not the same

Object State Equality

Consider Foo has the following properties, for the above these would have received the default values right? So 0 and Null, so why did the quality fail? We already know it was the memory reference not being the same as custom types like Foo are reference types.

1
2
3
4
5
public class Foo
{
public int Id { get; set; }
public string Desc { get; set; }
}

You can fix this by simply inheriting and implementing IEquatable<T> where T is the type you want to compare with.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public class Foo : IEquatable<Foo>
{
public int Id { get; set; }
public string Desc { get; set; }

public bool Equals(Foo other)
{
if (ReferenceEquals(other, null))
return false;

if (ReferenceEquals(this, other))
return true;

return (Id == other.Id
&& Desc == other.Desc);
}

/*
This method is used to return the hash code for this instance. A hash code is a numeric value which is used to insert and identify an object in a hash-based collection. The GetHashCode method provides this hash code for algorithms that need quick checks of object equality.
*/
public override int GetHashCode()
{
// Logical exclusive OR operator ^ is for compound assignment
int hash = 0;
hash ^= Id.GetHashCode();
hash ^= Desc.GetHashCode();
return hash;
}
}

So now equals has been overridden to compare the state.

1
2
3
4
5
6
7
8
9
10
11
12
var obj1 = new Foo()
{
Id = 42,
Desc = "Hoe"
};
var obj2 = new Foo()
{
Id = 42,
Desc = "Hoe"
};

obj1.Equals(obj2) // true

References