Intersect with 2 EntityCollections via custom IEqualityComparer
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 t开发者_运维知识库o 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. }
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.
精彩评论