IEqualityComparer <t>中的令人费解的行为,不会遇到Equals()方法中的断点

时间:2016-08-04 10:27:54

标签: c# linq

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但从不等于。因此,我的比较者没有给出预期的结果。

任何人都能解释一下吗?

TIA。

1 个答案:

答案 0 :(得分:3)

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

GetHashCode() 必须相等对象返回相等哈希码(其中&#34;等于&#34;表示{ {1}}将返回Equals())。

由于没有足够的true值来为每个不同的对象(例如字符串)使用不同的哈希码,因此当然会有不同的共享相同哈希码的对象。

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

<强>结论:

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

OptionEntry