過載相等運算子
僅過載相等運算子是不夠的。在不同的情況下,可以呼叫以下所有內容:
object.Equals和object.GetHashCodeIEquatable<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);
}
}