0

The Equals ( object obj) method for HashSet Contains check is not behaving in expected manner and I am not able to root cause it. Any help will be appreciated.

I am using a C# HashSet to store class object POS. Have declared it as
public static HashSet Store = new HashSet();

On calling Store.Add (A) A is stored in the Hashset properly.

When i try Store.Contains(B) for the case when GetHasCode returns the same hascode for A and B, the Equals method is called. The problem I am facing is in the Equal method I never get invocation for obj A. It ways gives me obj B as reference and hence evaluates to true. Since the hascode for both A and B are same should Equals not be called with obj A as reference?

/* The class object to be entered in Hashset is given below */

public class POS  
{
    private int[] R = new int[Constants.MaxN];
    public int prev;

    /**  Methods for the class goes here **/


   /* To use enter the object in Hashset placed the GetHashCode and Equals functions below */
   public override int GetHashCode()
    {
        uint val=0;
        uint temp = 0;
        int j = 0;
        for (long i = 0; i < Globals.GetN(); i++)
        {
            if (i > 9) { break; }
            temp = (uint)R[i];
            j = (int)i * 3;
            val |= (temp << j);
        }
        return (int) val; 
        }
   public override bool Equals(object obj)
   {
       int temp, tmp;
       var POSitem = obj as POS;
       Console.WriteLine("Entered:");
       if (obj == null) { return false; }
       if (ReferenceEquals(this, POSitem)) return true;

       for (int i = 0; i < Globals.GetN(); i++)
       {
           temp = this.Give(i);
           tmp = POSitem.Give(i);
           if (temp != tmp) return false;
       }
       return true;

   }
} // end braces of POS 
  • 3
    It doesn't matter. `Equals` should be symmetric, reflexive and transitive, therefore you have to implement it so that `a.Equals(b) == b.Equals(a)` – Lucas Trzesniewski Oct 06 '14 at 12:29
  • What version of .NET are you using? If it's anything over .NET 1.1 you'd be better off implementing `IEquatable`. As that's type safe due to generics, you don't need to worry about overriding `GetHashCode()`. – krillgar Oct 06 '14 at 12:29
  • 6
    @krillgar You always have to override `Equals` and `GetHashCode` in tandem - so no if he overrides `Equals` he has to override `GetHashCode` as well, especially when using a `HashSet`. I wrote an explanation [here](http://stackoverflow.com/a/26202958/3764814). – Lucas Trzesniewski Oct 06 '14 at 12:31
  • 1
    It sounds like you are saying it calls `b.Equals(b)` and you don't know why. We need to see the code for all these adds you are talking about. A paragraph of text is not as useful. – weston Oct 06 '14 at 12:41

1 Answers1

0

It's really hard to follow what you're asking here; many spelling and grammar mistakes. But, from what I've been able to understand you're saying that in a collection of two objects (call them A and B) and that you're wondering why that when you add B only A.Equals is being called.

A.Equals(B) is called to figure out if A equals B. If A equals B then B equals A and there's no reason to invoke B.Equals(A). This is the symmetric property of equality.

Peter Ritchie
  • 35,463
  • 9
  • 80
  • 98