0

I have implemented a equality comparer in below manner.

class BoxEqualityComparer : IEqualityComparer<Box>
{
    public bool Equals(Box b1, Box b2)
    {
        if (b2 == null && b1 == null)
           return true;
        else if (b1 == null | b2 == null)
           return false;
        else if(b1.Height == b2.Height && b1.Length == b2.Length
                            && b1.Width == b2.Width)
            return true;
        else
            return false;
    }

    public int GetHashCode(Box bx)
    {
        int hCode = bx.Height ^ bx.Length ^ bx.Width;
        return hCode.GetHashCode();
    }
}

Then I have created a Dictionary, in that I will add some values. So here it will compare object based on it's properties (height, width, length). I am getting the expected output. But I am wondering about the execution of GetHashCode method. I put a breakpoint in there, but I am unable to debug it. My question is when does GeHashCode method will be executed and how many times?

class Example
{
   static void Main()
   {
      BoxEqualityComparer boxEqC = new BoxEqualityComparer();

      var boxes = new Dictionary<Box, string>(boxEqC);

      var redBox = new Box(4, 3, 4);
      AddBox(boxes, redBox, "red");

      var blueBox = new Box(4, 3, 4);
      AddBox(boxes, blueBox, "blue");

      var greenBox = new Box(3, 4, 3);
      AddBox(boxes, greenBox, "green");
      Console.WriteLine();

      Console.WriteLine("The dictionary contains {0} Box objects.",
                        boxes.Count);
   }

   private static void AddBox(Dictionary<Box, String> dict, Box box, String name)
   {
      try {
         dict.Add(box, name);
      }
      catch (ArgumentException e) {
         Console.WriteLine("Unable to add {0}: {1}", box, e.Message);
      }
   }
}

public class Box
{
    public Box(int h,  int l, int w)
    {
        this.Height = h;
        this.Length = l;
        this.Width = w;
    }

    public int Height { get; set; }
    public int Length { get; set; }
    public int Width { get; set; }

    public override String ToString()
    {
       return String.Format("({0}, {1}, {2})", Height, Length, Width);
    }
}
Power Star
  • 1,724
  • 2
  • 13
  • 25
  • You you use `ContainsKey` for example but also at `dict.Add(box, name)` so it should be called. Try clean and rebuild with Debug configuration. – Tim Schmelter Aug 17 '17 at 09:31

1 Answers1

0

See https://referencesource.microsoft.com/#mscorlib/system/collections/generic/dictionary.cs,fd1acf96113fbda9.

Add(key, value) calls the insert method, which in turn will always calculate a hash code via

int hashCode = comparer.GetHashCode(key) & 0x7FFFFFFF;

So in other words, each call to Dictionary.Add should always trigger a calculation of the key's hash via the IEqualityComparer you provided.

As for your example code, this works fine for me, VS 2015 does break at BoxEqualityComparer.GetHashCode() for me.

Bogey
  • 4,926
  • 4
  • 32
  • 57
  • On add will it call only gethashcode method or also equal method? – Power Star Aug 17 '17 at 09:42
  • It also hits your comparer's Equals method eventually for me, specifically the second time you're calling AddBox. (-> Dictionary.Add -> Dictionary.Insert (see line 334 in the Dictionary class' source code linked) – Bogey Aug 17 '17 at 09:48