Overloading equality operators C# with Example
Overloading just equality operators is not enough. Under different circumstances, all of the following can be called: 1. object.Equals and object.GetHashCode 2. IEquatable.Equals (optional, allows avoiding boxing) 3. operator == and operator != (optional, allows using operators) When overriding Equals, GetHashCode must also be overridden. When implementing Equals, there are many special cases: comparing to objects of a different type, comparing to self etc. When NOT overridden Equals method and == operator behave differently for classes and structs. For classes just references are compared, and for structs values of properties are compared via reflection what can negatively affect performance. == can not be used for comparing structs unless it is overridden. Generally equality operation must obey the following rules: Must not throw exceptions. Reflexivity: A always equals A (may not be true for NULL values in some systems). Transitvity: if A equals B, and B equals C, then A equals C. If A equals B, then A and B have equal hash codes. Inheritance tree independence: if B and C are instances of Class2 inherited from Class1: Class1.Equals(A,B) must always return the same value as the call to Class2.Equals(A,B). class Student : IEquatable { public string Name { get; set; } = ""; public bool Equals(Student other) { if (ReferenceEquals(other, null)) return false; if (ReferenceEquals(other, this)) return true; return string.Equals(Name, other.Name); } public override bool Equals(object obj) { if (ReferenceEquals(null, obj)) return false; if (ReferenceEquals(this, obj)) return true; return Equals(obj as Student); } public override int GetHashCode() { return Name?.GetHashCode() ?? 0; } public static bool operator ==(Student left, Student right) { return Equals(left, right); } public static bool operator !=(Student left, Student right) { return !Equals(left, right); } }