为什么不.Except()和Intersect()在这里使用LINQ工作?

时间:2010-08-06 00:42:09

标签: c# linq collections

我有以下代码似乎无法正常工作:

上下文 我有两个对象列表:
* listOne有100条记录
* listTwo有70条记录

其中许多具有相同的Id属性(在两个列表中);

 var listOneOnlyItems = listOne.Except(listTwo, new ItemComparer ());

这是比较器

public class ItemComparer : IEqualityComparer<Item>
{
    public bool Equals(Item x, Item y)
    {
        if (x.Id == y.Id)
            return true;

        return false;
    }

    public int GetHashCode(Item obj)
    {
        return obj.GetHashCode();
    }
}

运行此代码后查看结果

listOneOnlyItems 

仍然有100条记录(应该只有30条记录)。任何人都可以帮助我吗?

另外,正在运行

    IEnumerable<Item> sharedItems = listOne.Intersect(listTwo, new ItemComparer());

在sharedItems集合中返回零reesults

3 个答案:

答案 0 :(得分:6)

public int GetHashCode(Item obj)
{
    return obj.Id.GetHashCode();
}

至少值得检查 - IIRC GetHashCode()在相等之前首先进行测试,如果它们没有相同的哈希,则不会费心检查相等性。我不确定对obj.GetHashCode()的期望是什么 - 这取决于您在Item课程中实施的内容。

答案 1 :(得分:0)

考虑使GetHashCode()返回obj.Id.GetHashCode()

答案 2 :(得分:0)

此代码可以正常工作:

static void TestLinqExcept()
{
    var seqA = Enumerable.Range(1, 10);
    var seqB = Enumerable.Range(1, 7);
    var seqAexceptB = seqA.Except(seqB, new IntComparer());
    foreach (var x in seqAexceptB)
    {
        Console.WriteLine(x);
    }
}

class IntComparer: EqualityComparer<int>
{
    public override bool Equals(int x, int y)
    {
        return x == y;
    }

    public override int GetHashCode(int x)
    {
        return x;
    }
}

您需要在EqualityComparer方法中添加“覆盖”关键字。 (我认为没有'覆盖'是隐含的,这是C#设计师的一个错误。)