Using GetHashCode in Equals I have a scenario when I want to have a HashSet&lt;ITrackableObjectData&gt;, where ITrackableObjectData has string TypeName and object Id readonly immutable properties. Id is a primitive value, ie. string, int, long, Guid etc.

I want to use these equality rules:


If the TypeName property is different, should anyway be considered non-equal.
If the Id is zero, null etc, should use the base object hashcode (reference equal).
If Id is not zero, then it should compare the TypeName and Id.


I created the following comparer to provided to the HashSet's constructor, and I'd like to hear from you of any improvements/vandalism in my code. As you can see I'm using the GetHashCode in the Equals method, is this a bad-idea?
Note that these are my equality requirements in my scenario.

class ITrackableObjectDataComparer : EqualityComparer&lt;ITrackableObjectData&gt;
{
  public override bool Equals(ITrackableObjectData x, ITrackableObjectData y) =&gt;
    GetHashCode(x) == GetHashCode(y);

  public override int GetHashCode(ITrackableObjectData obj)
  {
    if (obj == null) return 0;
    var typeHash = obj.TypeName == null ? 0 : obj.TypeName.GetHashCode();
    var idHash = obj.Id == null ? 0 : obj.Id.GetHashCode();
    idHash = idHash == 0 ? obj.GetHashCode() : idHash;
    return typeHash ^ idHash;
  }
}


Note that this EqualityComparer is a private class and is only meant to serve the purpose of this specific HashSet which is not exposed at all.
In fact I don't also really care about the Equals, but rather about the GetHashCode, so I know whether an object with my specs have already been added to a HashSet.

Update:

This is basically the equality checker that fulfills my requirements (but again, I don't need an equality comparer, I need a hash equality-comparer)

public override bool Equals(ITrackableObjectData x, ITrackableObjectData y)
{
  if (x == y) return true; //ref eq.
  else if (x == null)
    return y == null;
  else if (y == null)
    return false;
  else if (x.TypeName != y.TypeName)
    return false;
  else
  {
    if (x.Id == null)
      return y.Id == null;
    else if (y.Id == null)
      return false;
    else
    {
      int xId = x.Id.GetHashCode(),
          yId = y.Id.GetHashCode();
      if (xId == 0 || yId == 0)
        return x.Equals(y); //use default eq.
      else
        return xId == yId;
    }
  }
}
I think you are missing the point. Different objects can produce same hashcode. This can happen:

obj.Equals(otherObj)  // false
obj.GetHashCode() == otherObj.GetHashCode() //true


If for some reason you want your Equals methods to return true when hashcodes are equal, then by all means. Make sure to document this behavior though. 

However if you want to compare references , then use ReferenceEquals method instead. Hashcode comparison will not work for that scenario, because hashcode equality does not guarantee that object are (reference-)equal.

P.S. Also keep in mind, that hashcodes should not change, otherwise hash-tables might break. Make sure that Id and TypeName are read-only properties.