IComparable 是一个接口,它定义了实现类的两个实例可以被视为大于、小于或等于彼此。由于您在该接口的方法中定义了相等性,因此您还需要重写 Equals 方法(和相等运算符)以确保两者的结果一致。
public class EqualityTest : IComparable<EqualityTest>
{
public int Value { get; set; }
public int CompareTo(EqualityTest other)
{
return this.Value.CompareTo(other.Value);
}
}
在上面的示例中,我实现了 IComparable,但没有覆盖 Equals。如果您使用具有相同值的类的两个单独实例调用 CompareTo,它将说它们是相等的。如果你用相同的两个实例调用 Equals,它会说它们 not 相等,因为它会测试它们是否是同一个对象(Equals 的默认实现)。
两个相等的项应该返回相同的哈希码(用于快速查找用作哈希表中键的项),因此如果您覆盖 Equals,那么您还应该覆盖 GetHashCode()
例如,我刚刚在我的 IDE 中创建了以下类:
public class EqualityTest
{
public string A { get; set; }
public string B { get; set; }
}
然后运行 Resharper 有用的“生成平等”功能,说我希望 A 和 B 都影响平等。这是它创建的代码:
public bool Equals(EqualityTest other)
{
if (ReferenceEquals(null, other))
{
return false;
}
if (ReferenceEquals(this, other))
{
return true;
}
return Equals(other.A, A) && Equals(other.B, B);
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj))
{
return false;
}
if (ReferenceEquals(this, obj))
{
return true;
}
if (obj.GetType() != typeof(EqualityTest))
{
return false;
}
return Equals((EqualityTest)obj);
}
public override int GetHashCode()
{
unchecked
{
return ((A != null ? A.GetHashCode() : 0)*397) ^ (B != null ? B.GetHashCode() : 0);
}
}
public static bool operator ==(EqualityTest left, EqualityTest right)
{
return Equals(left, right);
}
public static bool operator !=(EqualityTest left, EqualityTest right)
{
return !Equals(left, right);
}
因此,如果您要覆盖 Equals,那么您还应该定义以上所有内容以确保一致性,如果您正在实施 IComparable,那么同样适用。