[英]IEqualityComparer and Linq Distinct - Hard Code GetHashCode()
I have an array of CustomObject
s and a custom IEqualityComparer<CustomObject>
. 我有一个CustomObject
数组和一个自定义IEqualityComparer<CustomObject>
。 I have hard coded the IEqualityComparer.GetHashCode()
method to return a constant 42
. 我已经对IEqualityComparer.GetHashCode()
方法进行了硬编码,以返回常量42
。
When I run linq's Distinct
method on the array, nothing is filtered out. 当我在数组上运行linq的Distinct
方法时,没有任何过滤掉。 Anyone know why? 谁知道为什么?
Note: I know there are a number of questions on here about this issue, however, the ones I've seen ( C# Distinct on IEnumerable<T> with custom IEqualityComparer , Distinct() with lambda? , etc) only say to make sure to implement GetHashCode
. 注意:我知道这里有很多关于这个问题的问题,但是,我看过的( C#Distinct on IEnumerable <T> with custom IEqualityComparer , Distinct()with lambda? )等只是为了确保实现GetHashCode
。 None of them explain, why it doesn't work . 他们都没有解释, 为什么它不起作用 。
Code: 码:
public class CustomObject
{
public string Name { get; set; }
}
public class CustomObjectEqualityComparer : IEqualityComparer<CustomObject>
{
public bool Equals(CustomObject x, CustomObject y)
{
//Every CustomObject should now be 'equal'!
return x.GetHashCode() == y.GetHashCode();
}
public int GetHashCode(CustomObject obj)
{
//Every CustomObject should now be 'equal'!
return 42;
}
}
Test: 测试:
[TestFixture]
public class TestRunner
{
private CustomObject[] customObjects =
{
new CustomObject {Name = "Please"},
new CustomObject {Name = "Help"},
new CustomObject {Name = "Me"},
new CustomObject {Name = "Stack"},
new CustomObject {Name = "Overflow"},
};
[Test]
public void DistinctTest()
{
var distinctArray =
customObjects.Distinct(new CustomObjectEqualityComparer()).ToArray();
//Since every CustomObject is 'Equal' there should only be
//1 element in the array.
Assert.AreEqual(1, distinctArray.Length);
}
}
This is the output I get from running the test: 这是我从运行测试得到的输出:
Expected: 5
But was: 1
If I debug the test, I can see that GetHashCode
is being called, so why isn't Distinct
filtering out all the 'duplicates'? 如果我调试测试,我可以看到正在调用GetHashCode
,那么为什么不Distinct
过滤掉所有'重复'?
When I run linq's Distinct method on the array, nothing is filtered out. 当我在数组上运行linq的Distinct方法时,没有任何过滤掉。 Anyone know why? 谁知道为什么?
Yes - Equals
is going to return false
for any two distinct objects. 是 - 对于任何两个不同的对象, Equals
将返回false
。 Within your Equals
implementation, you're calling the CustomObject.GetHashCode
method (which isn't overridden), not your custom comparer's GetHashCode
method. 在Equals
实现中,您将调用CustomObject.GetHashCode
方法(未被覆盖), 而不是自定义比较器的GetHashCode
方法。 If you expected Equals
to call your custom GetHashCode
method, you'd need to change it to: 如果您希望Equals
调用自定义GetHashCode
方法,则需要将其更改为:
public bool Equals(CustomObject x, CustomObject y)
{
return GetHashCode(x) == GetHashCode(y);
}
Or given the implementation of GetHashCode(CustomObject)
, you can just simplify it to: 或者给定GetHashCode(CustomObject)
的实现,您可以将其简化为:
public bool Equals(CustomObject x, CustomObject y)
{
return true;
}
Note that your GetHashCode
method was being called by Distinct()
, but it was then calling your Equals
method to check that the objects were really equal... and at that point you were saying that they weren't (barring a massive coincidence). 请注意,你的GetHashCode
方法是由Distinct()
调用的,但是它正在调用你的Equals
方法来检查对象是否真的相等......那时你就是说它们不是(除非是巧合) 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.