runtime: Contract between GetHashCode and Equals methods broken in HashSetEqualityComparer

In https://msdn.microsoft.com/en-us/library/system.collections.iequalitycomparer.gethashcode(v=vs.110).aspx?f=255&MSPPError=-2147217396 Under Notes to Implementers:

  • Implementations are required to ensure that if the Equals method returns true for two objects x and y,
  • then the value returned by the GetHashCode method for x must equal the value returned for y.
var comp1 = HashSet<HashSet<string>>.CreateSetComparer();
var comp2 = HashSet<string>.CreateSetComparer();
var l1 = new HashSet<HashSet<string>>(comp2);
var l2 = new HashSet<HashSet<string>>(comp2);

var set1 = new HashSet<string>() {"a"};
var set2 = new HashSet<string>() {"a"};
l1.Add(set1);
l2.Add(set2);


Console.WriteLine(comp1.Equals(l1,l2));
Console.WriteLine(comp1.GetHashCode(l1) == comp1.GetHashCode(l2));

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Reactions: 1
  • Comments: 16 (15 by maintainers)

Commits related to this issue

Most upvoted comments

In favour of the API approach is that really doing this correctly involves having a comparer parameter.

Apologies, I missed that it takes a comparer. I got it into my head that you had suggested also replacing the existing method with an identical-but-differently-named one.

I would be good with an overload alongside the existing method to provide both compat and better correctness. If that’s the path we want to take then it may be better to open a new API addition issue specifically for the overload, and close this one out since we won’t be fixing it directly.

@unshorn if you enclose the code in three back ticks ``` and close it with the same it should show up clearer.