IEqualityComparer and Linq Distinct - Hard Code GetHashCode(

本文关键字:Code GetHashCode Hard and Linq Distinct IEqualityComparer | 更新日期: 2023-09-27 18:13:09

我有一个CustomObject s数组和一个自定义IEqualityComparer<CustomObject>。我已经硬编码的IEqualityComparer.GetHashCode()方法返回一个常数42

当我在数组上运行linq的Distinct方法时,没有任何内容被过滤掉。有人知道为什么吗?

注意:我知道这里有很多关于这个问题的问题,但是,我看到的(c# Distinct on IEnumerable与自定义IEqualityComparer, Distinct()与lambda?等)只说要确保实现GetHashCode。他们都没有解释为什么它不起作用

代码:

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;
    }
}
测试:

[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);
    }
}

这是我运行测试得到的输出:

 Expected: 5
 But was:  1

如果我调试测试,我可以看到GetHashCode正在被调用,那么为什么Distinct不过滤掉所有的"重复"?

IEqualityComparer and Linq Distinct - Hard Code GetHashCode(

当我在数组上运行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;
}

注意你的GetHashCode方法Distinct()调用,但它随后调用你的Equals方法来检查对象是否真的相等…那时候你说他们不是(除非是巨大的巧合)。