简体   繁体   English

IEqualityComparer和Linq Distinct - 硬代码GetHashCode()

[英]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 IEqualityComparerDistinct()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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM