C# i可比与等于()
从 实现IComparable的类型必须重写Equals。重写Equals的类型也必须重写GetHashCode;否则,哈希表可能无法正常工作C# i可比与等于(),c#,C#,从 实现IComparable的类型必须重写Equals。重写Equals的类型也必须重写GetHashCode;否则,哈希表可能无法正常工作 我不太明白。任何人都可以解释。IComparable是一个接口,它定义了实现类的两个实例可以被视为彼此大于、小于或等于。由于在该接口的方法中定义了相等,因此还需要重写Equals方法(和相等运算符),以确保这两个方法的结果一致 public class EqualityTest : IComparable<EqualityTest> {
我不太明白。任何人都可以解释。IComparable是一个接口,它定义了实现类的两个实例可以被视为彼此大于、小于或等于。由于在该接口的方法中定义了相等,因此还需要重写Equals方法(和相等运算符),以确保这两个方法的结果一致
public class EqualityTest : IComparable<EqualityTest>
{
public int Value { get; set; }
public int CompareTo(EqualityTest other)
{
return this.Value.CompareTo(other.Value);
}
}
然后运行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,则同样适用。有两种方法可以比较代码中的对象:
Equals
和GetHashCode
为了在所有情况下正确比较对象,当覆盖Equals
方法(用于某些比较)时,还必须覆盖GetHashCode
(在其余情况下使用)
如果覆盖其中一个对象而不是另一个对象,则可能会得到意外的结果。IComparable用于比较两个对象-如果认为它们相等,则Compare将返回0。如果两个对象的IComparable.Compare返回零,而obj1.Equals(obj2)返回false,这将是非常意外的,因为这意味着两个对象具有两种不同的相等含义
当一个类重写Equals时,它也应该重写GetHashCode,因为两个相等的对象应该散列为相同的值,此散列应基于实现相等时使用的字段/属性。有关Equals和GetHashCode之间的关系的更多信息:还请注意,尽管在每种情况下都必须遵守IComparable、Equals和GetHashCode()的约定,但不一定要显式实现所有三个,只要取得一致的结果。主要是指具有相同哈希代码的两个对象相等,并在CompareTo()上返回0。@rushinge我认为该语句是错误的:“主要是指具有相同哈希代码的两个对象相等,在CompareTo()上返回0。”。如果对象相等,建议GetHashCode()返回相同的值,CompareTo()返回0。如果IComparable.Compare返回零,则可以轻松生成不同/不相等的实例,这些实例返回相同的哈希代码:),这是否真的意味着这些项应该被视为相等的,或者仅仅是不存在明确的有序关系?假设有一个不可变的类ScheduleEvent,其中包括DateTime类型的EventTime和MethodInvoker类型的EventAction字段。ScheduleEvent对象将具有基于EventTime的自然顺序,但我认为具有相同EventTime但不同委托的ScheduleEvent对象应该从CompareTo返回0,但从Equals返回False。在我看来,如果存在一种可能性,即一个类型通常有一个明确的排序顺序,但可能存在一组相互不等价的值,但它们之间没有自然的相对排序,那么
CompareTo()就完全合适了
返回零,但对于Equals()
返回false(例如,我认为Decimal
在比较1.0m
和1.00m
时应该这样做)。在我看来,Equals
应该定义一个相对严格的相等关系,即使在=
或CompareTo
可能定义一个更宽松的相等关系的情况下。
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);
}