通过自定义IEqualityComparer与2个EntityCollections相交

时间:2011-01-24 17:12:53

标签: c# gethashcode iequalitycomparer intersect entitycollection

不要过多地重复这个问题,但我已经进行了搜索并且结果空洞。所以我有两个类型为T的EntityCollections,我想在每个中找到常见项目。抓到了吗?除一个以外的所有字段必须匹配因此,例如,如果类型T是类型CustomSet,并且CustomSet包括字段F1,F2,F3和FK字段OtherId,F1,F2和F3必须匹配(它们可以是字符串,整数,任何东西),而OtherId将永远不会比赛。我目前的实施:

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

永远不会产生任何结果,因为即使字段F1,F2和F3可能匹配,OtherId列也不会在任何其他集合中匹配。所以我建议使用IEqualityComparer的自定义实现,如下所示:

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();
    }

现在,我只测试这个,所以传入的obj是CustomSet类型,如果我可以使其正常运行,我将为其他类型添加必要的if语句。我知道Intersect扩展使用GetHashCode而不是Equals来比较项目,这就是为什么我真的不关心我的等于什么,因为这个类永远不会被调用,而是用于EntityCollections上的Intersect扩展。问题是,这不起作用。在我的测试集中,我知道我的'source'集合中有28个项目,我的'destination'集合中有28个项目,并且所有字段都匹配(显然除了OtherId字段)。我循环了GetHashCode代码,因为它循环了56次,并且能够匹配每组中所有28个项目的哈希码,但“交叉点”产生了0个计数。有什么我做错了,或者丢失了吗?谢谢。     }

1 个答案:

答案 0 :(得分:1)

这是你的问题:

  

我知道Intersect扩展使用GetHashCode而不是Equals来比较项目,这就是为什么我真的不关心我的等于什么,因为这个类永远不会被调用,而是用于EntityCollections上的Intersect扩展。

这根本不是真的。 GetHashCode被用作第一个“快速”分组值的方式,但仍然会为具有相同哈希值的任何项目调用Equals,否则您无法知道它们是相等的。

这就是散列表等总是有效的方式:由于性能原因可行,但是允许发生碰撞时,散列值应该是不相等的值。