【问题标题】:Implementing EqualityCompare vs overriding GetHashCode and Equals实现 EqualityCompare 与覆盖 GetHashCode 和 Equals
【发布时间】:2017-10-20 04:12:31
【问题描述】:

我创建了两个几乎相同的类。两者都代表一个 Pair (x,y) 但在其中一个中我覆盖了 GetHashCode 和 Equals 方法。有人告诉我,当 HashCode 不同时,Collections 会将它们视为不同的元素,甚至不会费心将它们与等号进行实际比较。然而,事实证明,我为不覆盖 GetHashCode 和 Equals 的类实现了一个 EqualityComparer,即使 HashCodes 仍然不同,也一切正常。

看看我的控制台项目:

using System;
using System.Collections.Generic;
using System.Linq;

namespace matrixExample
{
    class Program
    {

        static void Main(string[] args)
        {
            Console.WriteLine("Same Hash but no insertion: as expected");
            HashSet<MyPair> hash = new HashSet<MyPair>();
            MyPair one = new MyPair { X = 10, Y = 2 };
            MyPair copyOfOne = new MyPair { X = 10, Y = 2 };
            Console.WriteLine(one.GetHashCode() + " " +  hash.Add(one));
            Console.WriteLine(copyOfOne.GetHashCode() + " " + hash.Add(copyOfOne));


            Console.WriteLine("-----------------------------------------");

            Console.WriteLine("Different Hash but no insertion! why?");
            HashSet<MyPairWithoutOverride> hash2 = new HashSet<MyPairWithoutOverride>(new SameHash());
            MyPairWithoutOverride a1 = new MyPairWithoutOverride { X = 10, Y = 2 };
            MyPairWithoutOverride a1copy = new MyPairWithoutOverride { X = 10, Y = 2 };
            Console.WriteLine(a1.GetHashCode() + " " + hash2.Add(a1));
            Console.WriteLine(a1copy.GetHashCode() + " " + hash2.Add(a1copy));

        }

        public class MyPair
        {
            public int X { get; set; }
            public int Y { get; set; }

            public override int GetHashCode()
            {
                return X * 10000 + Y;
            }

            public override bool Equals(object obj)
            {
                MyPair other = obj as MyPair;
                return X == other.X && Y == other.Y;
            }
        }

        public class MyPairWithoutOverride
        {
            public int X { get; set; }
            public int Y { get; set; }
        }

        public class SameHash : EqualityComparer<MyPairWithoutOverride>
        {
            public override bool Equals(MyPairWithoutOverride p1, MyPairWithoutOverride p2)
            {
                return p1.X == p2.X && p1.Y == p2.Y;
            }
            public override int GetHashCode(MyPairWithoutOverride i)
            {
                return base.GetHashCode();
            }
        }

    }
}

【问题讨论】:

    标签: c# collections hashcode iequalitycomparer


    【解决方案1】:

    你的问题来了

    public override int GetHashCode(MyPairWithoutOverride i)
    {
        return base.GetHashCode();
    }
    

    您返回的是base.GetHashCode(),它实际上是SameHash 类的哈希码。所以你实际上每次都返回相同的哈希码。

    如果您返回i.GetHashCode(),那么它将按预期运行。

    【讨论】:

    • 所以 Collection 实际上是在比较 SameHash 类的哈希值,这就是为什么它仍然可以工作的原因。知道了!谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-18
    • 1970-01-01
    • 1970-01-01
    • 2012-03-08
    相关资源
    最近更新 更多