Question

Not to repeat this question too much, but I already did a search and came up empty on a result. So I have two EntityCollections of type T and I would like to find the common items in each. The catch? All fields except one must match. So for example, if type T is a type CustomSet, and CustomSet includes fields F1, F2, F3 and a FK field OtherId, F1, F2 and F3 must match (they could be strings, ints, anything really) and the OtherId will never match. My current implementation:

var intersections = source.Intersect(destination).ToList();

will never yield any results because that OtherId column will never match in any other collection, even though the fields F1, F2 and F3 may match. So I'm proposing a custom implementation of IEqualityComparer which looks like this:

var intersections = source.Intersect(destination, new EntityCollectionComparer<T>()).ToList();

public class EntityCollectionComparer<T> : IEqualityComparer<T>
{
    #region IEqualityComparer<T> Members

    public bool Equals(T x, T y)
    {
        if (x.Equals(y))
            return true;
        else
            return false;
    }

    public int GetHashCode(T obj)
    {
        if (obj is CustomSet)
        {
            CustomSet temp = obj as CustomSet;

            return (temp.F1.GetHashCode() ^ temp.F2.GetHashCode() ^ temp.F3.GetHashCode());
        }
        return obj.GetHashCode();
    }

Now, I'm only testing this so the obj getting passed in is of type CustomSet, I will add the necessary if statements for my other types if I can get this to function properly. I know that the Intersect extension uses the GetHashCode instead of the Equals to compare items which is why I really don't care what's in my equals as this class will never be called but for the Intersect extension on EntityCollections. The thing is, this doesn't work. On my test set, I know I have 28 items in my 'source' collection, and 28 items in my 'destination' collection, and all the fields match (obviously except for the OtherId field). I stepped through the GetHashCode code as it looped 56 times and was able to match up hash codes on all 28 items from each set yet the 'intersections' yielded 0 count. Is there something I'm doing wrong, or missing? Thanks. }

Was it helpful?

Solution

This is your problem:

I know that the Intersect extension uses the GetHashCode instead of the Equals to compare items which is why I really don't care what's in my equals as this class will never be called but for the Intersect extension on EntityCollections.

That's simply not true. GetHashCode is used as a first "quick" way of bucketing values, but Equals will still be called for any items with the same hash, otherwise you can't know they're equal.

That's the way hash tables etc always work: the hashes should be different for unequal values where feasible for performance reasons, but are allowed to collide.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top