IEqualityComparer中令人费解的行为,Equals() 方法中的断点未命中

本文关键字:方法 Equals 断点 令人费解 IEqualityComparer | 更新日期: 2023-09-27 18:00:06

VS2013, .Net 4.5.2.

给定此代码

            var opCollectionA = new List<Option>() 
            {
              ...some elements added here..
            };
            var opCollectionB = new List<Option>() 
            {
              ...some elements added here..
            };
            var InAandB = opCollectionA.Except(opCollectionB, new OptionComparer()).ToArray();

而这个比较器类:

public class OptionComparer : EqualityComparer<Option>
{
    public override bool Equals(Option x, Option y)
    {
        //Check whether the objects are the same object. 
        if (Object.ReferenceEquals(x, y)) return true;
        //Check whether the options have the same Entry value. 
        return x != null && y != null && x.OptionEntry.Equals(y.OptionEntry);
    }
    public override int GetHashCode(Option obj)
    {
        //Get hash code for the OptionSection field if it is not null. 
        int hashOptionSection = obj.OptionSection == null ? 0 : obj.OptionSection.GetHashCode();
        //Get hash code for the OptionEntry field. 
        int hashOptionEntry = obj.OptionEntry.GetHashCode();
        //Calculate the hash code for the Option. 
        return hashOptionSection ^ hashOptionEntry;
    }
}

我发现在调试模式下,每次比较都会调用 GetHashcode,但永远不会等于。因此,我的比较器没有给出预期的结果。

谁能解释一下?

蒂亚。

IEqualityComparer<T>中令人费解的行为,Equals() 方法中的断点未命中

哈希代码用于加快比较速度。因此,GetHashCode()实现应该比Equals更快。

GetHashCode()必须相等的对象返回相等的哈希码(其中"等于"表示Equals()将返回true (。

由于没有足够的int值为每个不同的对象(例如字符串(提供不同的哈希代码,因此当然会有不同的对象共享相同的哈希代码。

如果GetHashCode()为两个对象返回相同的哈希代码,则必须调用Equals()以确定它们是否真的相等。但是,如果GetHashCode()返回不同的值,您已经知道这些对象不能相等,并且不必调用通常更昂贵的Equals()方法。

结论:

在您的代码中,如果两个OptionOptionEntry相等,您似乎希望它们相等。因此,解决问题的最简单方法是更改GetHashCode(),以便它仅返回OptionEntry的哈希代码:

public override int GetHashCode(Option obj)
{
    return obj.OptionEntry.GetHashCode();
}