Overloading equality operators
suggest changeOverloading just equality operators is not enough. Under different circumstances, all of the following can be called:
object.Equalsandobject.GetHashCodeIEquatable<T>.Equals(optional, allows avoiding boxing)operator ==andoperator !=(optional, allows using operators)
When overriding Equals, GetHashCode must also be overriden. 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:
Aalways equalsA(may not be true forNULLvalues in some systems). - Transitvity: if
AequalsB, andBequalsC, thenAequalsC. - If
AequalsB, thenAandBhave equal hash codes. - Inheritance tree independence: if
BandCare instances ofClass2inherited fromClass1:Class1.Equals(A,B)must always return the same value as the call toClass2.Equals(A,B).
class Student : IEquatable<Student>
{
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);
}
}
Found a mistake? Have a question or improvement idea?
Let me know.
Table Of Contents