Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么';t.Except()和Intersect()在这里使用LINQ工作吗?_C#_Linq_Collections - Fatal编程技术网

C# 为什么';t.Except()和Intersect()在这里使用LINQ工作吗?

C# 为什么';t.Except()和Intersect()在这里使用LINQ工作吗?,c#,linq,collections,C#,Linq,Collections,我有以下代码似乎不起作用: 上下文: 我有两个对象列表: *listOne有100条记录 *清单二有70项记录 其中许多具有相同的Id属性(在两个列表中) 这是比较器 public class ItemComparer : IEqualityComparer<Item> { public bool Equals(Item x, Item y) { if (x.Id == y.Id) return true; r

我有以下代码似乎不起作用:

上下文: 我有两个对象列表:
*listOne有100条记录
*清单二有70项记录

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

这是比较器

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();
    }
}
仍然有100条记录(应该只有30条)。有人能帮我吗

还有,跑步

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

在sharedItems集合中返回零个结果

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

至少值得检查一下——IIRC GetHashCode()在相等之前先进行测试,如果它们没有相同的哈希值,就不会麻烦检查相等性。我不确定从
obj.GetHashCode()
中可以得到什么——这取决于您在
类上实现了什么。

此代码工作正常:

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;
    }
}
静态void TestLinqExcept()
{
var Seka=可枚举范围(1,10);
var seqB=可枚举范围(1,7);
var seqAexceptB=seqA.Except(seqB,new IntComparer());
foreach(SekaExceptB中的变量x)
{
控制台写入线(x);
}
}
类IntComparer:EqualityComparer
{
公共覆盖布尔等于(整数x,整数y)
{
返回x==y;
}
公共覆盖int GetHashCode(int x)
{
返回x;
}
}

您需要将“覆盖”关键字添加到EqualityComparer方法中。(我认为C#设计器没有隐式地使用“override”是一个错误)。

你可以只键入“return(x.Id==y.Id)”,你知道。@Simon Brown-谢谢,但这并不能真正帮助回答问题,“Item”是否使用Id以外的东西实现GetHashCode?我在一个快速而肮脏的控制台应用程序中确认了这一点。奇怪,这修复了Except()的问题,但intersect()仍然显示零项。有什么想法吗?有趣的是——通过MSDN阅读,似乎
Intersect
(而不是
,除了
)使用了延迟执行——您可能看到了这一点吗?调用
.ToList()
应该强制实现数据。除此之外,我还被难住了(除了检查拼写错误)。两者的比较器应该是相同的,并且应该以相同的方式调用(带有延迟执行警告)对不起,我刚才看到您正在实现IEqualityComparer。嗯,这是对我的测试代码的一个简单更改,它工作得很好。请注意,每次比较两个项目时都会调用GetHashCode。顺便问一下,您是否考虑过只使用seqA.Where(a=>!seqB.Contains(a)),这样就不需要使用IEqualityComparer了?或者,更好的方法是使用SortedSet之类的工具。
    IEnumerable<Item> sharedItems = listOne.Intersect(listTwo, new ItemComparer());
public int GetHashCode(Item obj)
{
    return obj.Id.GetHashCode();
}
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;
    }
}