C# IEqualityComparer和Linq Distinct-硬代码GetHashCode()
我有一个C# IEqualityComparer和Linq Distinct-硬代码GetHashCode(),c#,.net,linq,linq-to-objects,C#,.net,Linq,Linq To Objects,我有一个CustomObjects数组和一个自定义IEqualityComparer。我已经硬编码了IEqualityComparer.GetHashCode()方法以返回常量42 当我在数组上运行linq的Distinct方法时,没有任何内容被过滤掉。有人知道为什么吗 注意:我知道这里有很多关于这个问题的问题,但是,我看到的(,等等)只是说确保实现GetHashCode。他们都没有解释为什么它不起作用 代码: 这是我从运行测试中获得的输出: Expected: 5 But was: 1
CustomObject
s数组和一个自定义IEqualityComparer
。我已经硬编码了IEqualityComparer.GetHashCode()
方法以返回常量42
当我在数组上运行linq的Distinct
方法时,没有任何内容被过滤掉。有人知道为什么吗
注意:我知道这里有很多关于这个问题的问题,但是,我看到的(,等等)只是说确保实现GetHashCode
。他们都没有解释为什么它不起作用
代码:
这是我从运行测试中获得的输出:
Expected: 5
But was: 1
如果我调试测试,我可以看到正在调用GetHashCode
,那么为什么不Distinct
过滤掉所有的“重复项”
当我在数组上运行linq的Distinct方法时,没有任何内容被过滤掉。有人知道为什么吗
是-Equals
将为任何两个不同的对象返回false
。在Equals
实现中,调用的是CustomObject.GetHashCode
方法(该方法未被重写),而不是自定义比较器的GetHashCode
方法。如果希望Equals
调用自定义GetHashCode
方法,则需要将其更改为:
public bool Equals(CustomObject x, CustomObject y)
{
return GetHashCode(x) == GetHashCode(y);
}
或者给定GetHashCode(CustomObject)
的实现,您可以将其简化为:
public bool Equals(CustomObject x, CustomObject y)
{
return true;
}
请注意,
Distinct()
正在调用您的GetHashCode
方法,但它随后调用了Equals
方法来检查对象是否真正相等。。。在那一点上,你说它们不是(除非有大量巧合)。如果相关,我使用的是.net 4.5.1
简单,你在平等期间调用CustomObject
上的GetHashCode
,而不是调用你的硬编码版本。Distinct
实现使用自定义比较器。它将首先调用GetHashCode
。如果发生冲突,它将调用Equals
,您在CustomObject
上没有覆盖它,因此将是一个参考哈希代码。但我正在传递我的CustomObjectEqualityComparer
。比较应该委托给这门课,对吗?该死,在阅读了Jon Skeet的回答后,我现在看到了,你是对的@Adamhuldsworth。谢谢是的,就是这样。谢谢你,乔恩!作为一个附带问题,这里是否已经有了一条线索,关于为什么GetHashCode()
和Equals()
都需要由Distinct
调用?我可以理解GetHashCode()
用于将对象放入HashTable
,但不能Distinct
假设如果散列相等,则对象相等?@ppittle不,它的工作方式是相反的,不同散列的两个对象不相等(这与声明具有相同散列的两个对象相等有细微的区别)。冲突会发生,因为散列缩小了可用值的范围,因此随后使用Equals
来测试真正的相等性。在没有太多冲突的情况下,这是一种性能/准确性权衡。
public bool Equals(CustomObject x, CustomObject y)
{
return GetHashCode(x) == GetHashCode(y);
}
public bool Equals(CustomObject x, CustomObject y)
{
return true;
}