Immature and Equal ()

From MSDN

Types that implement IComparable must override Equals.Types, which override Equals, must also override GetHashCode; otherwise, the Hashtable may not work correctly.

I did not quite understand. Can someone explain.

+7
c #
source share
3 answers

IComparable is an interface that determines that two instances of an implementation class can be considered larger, smaller, or equal to each other. Since you defined equality in the methods of this interface, you also need to override the Equals method (and the equality operator) to ensure that the results of the two are consistent.

public class EqualityTest : IComparable<EqualityTest> { public int Value { get; set; } public int CompareTo(EqualityTest other) { return this.Value.CompareTo(other.Value); } } 

In the above example, I implemented IComparable, but did not override Equals. If you choose CompareTo with two separate instances of the class with the same value, it will say that they are equal. If you call Equals with the same two instances, it will say that they are not equal, because it will check if they are the same object (standard implementation of Equals).

Two equal elements must return the same hash code (which is used to quickly find elements used as keys in hash tables), so if you override Equals, you must also override GetHashCode ()


As an example, I simply created the following class in my IDE:

 public class EqualityTest { public string A { get; set; } public string B { get; set; } } 

And he launched Resharper with the useful Generate Equality feature, saying that I wanted A and B to influence equality. This is the code he created:

  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); } 

So, if you override Equals, then you should also define all of the above to ensure consistency, if you implement IComparable, then the same applies.

+11
source share

IComparable is used to compare two objects - if they are considered equal, then Compare will return 0. It would be very unexpected if IComparable.Compare returned zero for two objects, but obj1.Equals (obj2) returned false, since that would mean two different equality values for objects.

When a class overrides Equals, it must also override GetHashCode, since two equal objects must have a hash with the same value, and this hash should be based on the fields / properties used to implement the equality.

+1
source share

There are two ways to compare objects in your code: Equals and GetHashCode

To correctly match the object in all situations when you override the Equals method (used for some comparisons), you must also override GetHashCode (used in the rest).

If you override one, but not the other, depending on your code, you may get unexpected results.

0
source share

All Articles