来自MSDN
实现IComparable的类型必须覆盖覆盖等于的Equals.Types,也必须重写GetHashCode;否则,哈希表可能无法正常工作。
我不太明白。谁能解释一下。
发布于 2009-09-14 12:42:56
IComparable是一个接口,它定义了实现类的两个实例可以被视为大于、小于或等于彼此。由于您已经在该接口的方法中定义了相等,所以还需要覆盖相等方法(和相等操作符),以确保这两个方法的结果是一致的。
public class EqualityTest : IComparable<EqualityTest>
{
public int Value { get; set; }
public int CompareTo(EqualityTest other)
{
return this.Value.CompareTo(other.Value);
}
}在上面的示例中,我实现了IComparable,但没有重写等于。如果使用具有相同值的类的两个单独实例调用CompareTo,则会说存在相等的值。如果使用相同的两个实例调用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);
}因此,如果您是重写等于,那么您还应该定义上述所有内容以确保一致性,如果您正在实现IComparable,则同样适用。
发布于 2009-09-14 12:44:33
IComparable用于比较两个对象--如果它们被认为相等,则比较将返回0。如果IComparable.Compare为两个对象返回零,而obj1.Equals(obj2)返回false,这将是非常意外的,因为这意味着对象具有两种不同的相等含义。
当类重写等于时,它也应该重写GetHashCode,因为两个相等的对象应该散列为相同的值,并且这个散列应该基于在实现相等时使用的字段/属性。
发布于 2009-09-14 12:43:49
代码中的对象可以通过两种方式进行比较:Equals和GetHashCode
为了在所有情况下正确地比较对象,当您重写Equals方法(用于某些比较)时,还必须重写GetHashCode (其余部分中使用)。
如果您根据您的代码覆盖其中一个而不是另一个,您可能会得到意想不到的结果。
https://stackoverflow.com/questions/1421289
复制相似问题