不要过多地重复这个问题,但我已经进行了搜索并且结果空洞。所以我有两个类型为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个计数。有什么我做错了,或者丢失了吗?谢谢。 }
答案 0 :(得分:1)
这是你的问题:
我知道Intersect扩展使用GetHashCode而不是Equals来比较项目,这就是为什么我真的不关心我的等于什么,因为这个类永远不会被调用,而是用于EntityCollections上的Intersect扩展。
这根本不是真的。 GetHashCode
被用作第一个“快速”分组值的方式,但仍然会为具有相同哈希值的任何项目调用Equals
,否则您无法知道它们是相等的。
这就是散列表等总是有效的方式:由于性能原因可行,但是允许发生碰撞时,散列值应该是不相等的值。