Mystery of Equality in C#: IEquatable<T>, IEqualityComparer<T>, IComparable<T>, IComparer<T>

  • Equals
  • GetHashCode
  • IEquatable<T>
  • IEqualityComparer<T>
  • IComparable<T>
  • IComparer<T>

Equals

public virtual bool Equals(Object obj)
class Student
{
public string Name { get; set; }
public int Number { get; set; }
public int SerialNo { get; set; }
public int Grade { get; set; }
}
public override bool Equals(object obj)
{
if (obj is Student student)
{
if (student.SerialNo == SerialNo)
return true;
else
return false;
}
else
return false;
}
Hashtable hashtable = new Hashtable();

hashtable.Add("MyFirstKey", 1);
hashtable.Add("MySecondKey", true);

if(hashtable.Contains("MySecondKey")) //it calls Equals
Console.WriteLine("I found it");

GetHashCode

public virtual int GetHashCode()
int a = 145;
Console.WriteLine(a.GetHashCode()); // 145
long a1 = 23; // a1.GetHashCode() => 23
long a2 = 23; // a2.GetHashCode() => 23
float f1 = 213.453f; // f1.GetHashCode() => 1129673720
float f2 = 213.453f; // f1.GetHashCode() => 1129673720
bool b1 = true; // b1.GetHashCode() => 1
bool b2 = true; // b2.GetHashCode() => 1
Student student1 = new Student()
{
Name = "Joe",
Grade = 3,
Number = 10,
SerialNo = 3213214
};

Student student2 = new Student()
{
Name = "Joe",
Grade = 3,
Number = 10,
SerialNo = 3213214
};
Console.WriteLine(student1.GetHashCode()); // 58225482
Console.WriteLine(student2.GetHashCode()); // 54267293
public override int GetHashCode()
{
return SerialNo.GetHashCode();
}
public override int GetHashCode()
{
return Number.GetHashCode() ^ SerialNo.GetHashCode();
}
  • When two variables’ hashcodes are equal, values of them maybe equal
  • When two variables’ hashcodes don’t equal, values of them surely are not equal
bool result = false;
if (student1.GetHashCode() == student2.GetHashCode())
result = student1.Equals(student2);

IEquatable<T>

public interface IEquatable<T>
{
bool Equals(T other);
}
class Student : IEquatable<Student>
{
public string Name { get; set; }
public int Number { get; set; }
public int SerialNo { get; set; }
public int Grade { get; set; }

public bool Equals(Student other)
{
if (other.SerialNo == SerialNo)
return true;
else
return false;
}
}
class Student : IEquatable<Student>
{
public string Name { get; set; }
public int Number { get; set; }
public int SerialNo { get; set; }
public int Grade { get; set; }

public bool Equals(Student other)
{
if (other.SerialNo == SerialNo)
return true;
else
return false;
}

public override bool Equals(object obj)
{
if (obj is Student student)
return Equals(student);
else
return false;
}

public override int GetHashCode()
{
return SerialNo.GetHashCode();
}
}

IEqualityComparer<T>

public interface IEqualityComparer<in T>
{
bool Equals(T x, T y);
int GetHashCode(T obj);
}
class SerialNoEqualityComparer : IEqualityComparer<Student>
{
public bool Equals(Student s1, Student s2)
{
if (s1 == null && s2 == null)
return true;
else if (s1 == null || s2 == null)
return false;
else if (s1.SerialNo == s2.SerialNo)
return true;
else
return false;
}

public int GetHashCode(Student student)
{
return student.SerialNo.GetHashCode();
}
}
class NumberEqualityComparer : IEqualityComparer<Student>
{
public bool Equals(Student s1, Student s2)
{
if (s1 == null && s2 == null)
return true;
else if (s1 == null || s2 == null)
return false;
else if (s1.Number == s2.Number)
return true;
else
return false;
}

public int GetHashCode(Student student)
{
return student.Number.GetHashCode();
}
}
List<Student> students = new List<Student>();
// Add some students to this List
var specificStudent = new Student()
{ SerialNo = 12, Number = 34, Grade = 3, Name = "Joe" };
bool exist1 = students
.Contains(specificStudent, new NumberEqualityComparer());
bool exist2 = students
.Contains(specificStudent, new SerialNoEqualityComparer());

IComparable<T>

public interface IComparable<in T>
{
int CompareTo(T other);
}
class Student : IComparable<Student>
{
public string Name { get; set; }
public int Number { get; set; }
public int SerialNo { get; set; }
public int Grade { get; set; }

public int CompareTo(Student other)
{
if (other.SerialNo < SerialNo)
return 1;
else if (other.SerialNo == SerialNo)
return 0;
else
return -1;
}
}
public int CompareTo(Student other)
{
return SerialNo.CompareTo(other.SerialNo);
}
List<Student> students = new List<Student>();
// add some students
students.Sort();

IComparer<T>

public interface IComparer<in T>
{
int Compare(T x, T y);
}
class SerialNoComparer : IComparer<Student>
{
public int Compare(Student s1, Student s2)
{
return s1.SerialNo.CompareTo(s2.SerialNo);
}
}
students.Sort(new SerialNoComparer());

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store