This project has moved. For the latest updates, please go here.

CompoundComparer doesn't create compound hash codes

Feb 21, 2014 at 11:22 AM
Edited Feb 21, 2014 at 11:38 AM
Hi again,

I was surprised to find recently that a compound comparer only uses the first non-null comparer to generate a hash code for an object, rather than creating a hash from all comparers in the composite.

Is that the case or is it just late and I've been at work too long?

If it is the case then I think it's misleading. I intuitively try to put the most coarse grained comparers first in order to avoid having to execute later (possibly more expensive) comparison steps. Unfortunately that's likely to significantly reduce the quality of the hash code produced by the first comparer.

For example: Imagine an elementwise collection equality comparer. The very first thing I would equate by is the length of the collection, because it's likely to be a very fast way to exclude a bunch of comparisons without even checking the elements. But now hash codes for the collections are likely to have many collisions and be clumped very heavily up one end of the range of possible hash codes.

Of course having to execute potentially expensive operations during the hash code generation might be counter to the whole idea of hash codes, but I would be prepared for that having made the comparer perform an expensive comparison in the first place. I would not so readily expect a very poor quality hash code based on only one comparer in the composite.

What are your thoughts? Could some kind of compromise be reached? Could each Comparer.ThenEquateBy() have another bool for 'contributesToHashCode' or something? Does that just pollute the API?
Feb 22, 2014 at 6:47 PM
In the current release, the compound comparer does currently only use the first non-null comparer.

I've already changed this behavior in the source. It's just waiting for me to fix up a few other things, and it should be in the next release.
Marked as answer by alpha_cast on 2/22/2014 at 4:50 PM