過載相等運算子
僅過載相等運算子是不夠的。在不同的情況下,可以呼叫以下所有內容:
- object.Equals和- object.GetHashCode
- IEquatable<T>.Equals(可選,允許避免拳擊)
- operator ==和- operator !=(可選,允許使用運算子)
當覆蓋 Equals 時,GetHashCode 也必須被覆蓋。在實現 Equals 時,有許多特殊情況:與不同型別的物件進行比較,與自我對比等。
當未覆蓋時 Equals 方法和 == 運算子對類和結構的行為不同。對於類,只比較引用,對於結構,通過反射比較屬性的值,這會對效能產生負面影響。== 不能用於比較結構,除非它被覆蓋。
通常,相等操作必須遵守以下規則:
- 不得丟擲異常。
- 反身性:A總是等於A(某些系統中的NULL值可能不正確)。
- Transitvity:如果 A等於B,B等於C,則A等於C。
- 如果 A等於B,則A和B具有相同的雜湊碼。
- 繼承樹獨立性:如果 B和C是從Class1繼承的Class2的例項:Class1.Equals(A,B)必須始終返回與呼叫Class2.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);
    }
}