简体   繁体   English

实现EqualityCompare与覆盖GetHashCode和Equals

[英]Implementing EqualityCompare vs overriding GetHashCode and Equals

I created two classes almost identical. 我创建了两个几乎完全相同的类。 Both represent a Pair (x,y) but in one of them I overrode the GetHashCode and Equals methods. 两者都表示一对(x,y),但是其中一个覆盖了GetHashCode和Equals方法。 I was told that when the HashCode is different the Collections takes them as different elements and does not even bother to actually compare them with the equals. 有人告诉我,当HashCode不同时,Collection将它们视为不同的元素,甚至不费心将它们与equals进行实际比较。 However, it turns out that I implemented an EqualityComparer for the class that do not override the GetHashCode and Equals and everything works fine even when the HashCodes are still different. 但是,事实证明,我为该类实现了一个EqualityComparer,该类不覆盖GetHashCode和Equals,即使HashCode仍然不同,一切也可以正常工作。

Take a look at my Console Project: 看一下我的控制台项目:

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

    }
}

Your problem is here 你的问题在这里

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

You're returning base.GetHashCode() which is actually the hash code of the SameHash class. 您将返回base.GetHashCode() ,它实际上是SameHash类的哈希码。 So you actually are returning the same hash code every single time. 因此,实际上您每次都返回相同的哈希码。

If you return i.GetHashCode() then it will behave as expected. 如果返回i.GetHashCode()则它将按预期运行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 linq&distinct,实现equals和gethashcode - linq & distinct, implementing the equals & gethashcode 实现Equals和GetHashCode-一种更简单的方法 - Implementing Equals and GetHashCode - an easier way 测试对象相等性的最佳方法是什么 - 不重写Equals和GetHashCode,或实现IEquatable <T> ? - What is the best way to test for object equality - without overriding Equals & GetHashCode, or implementing IEquatable<T>? 覆盖一个类型的Equals和GetHashCode,它有&#39;dibs&#39;? - Overriding the Equals and GetHashCode of a type, which has 'dibs'? 覆盖Equals和GetHashCode-派生类中的默认实现 - Overriding Equals and GetHashCode - default implementation in derived class 在C#中简化覆盖等于(),GetHashCode()以获得更好的可维护性 - Simplify Overriding Equals(), GetHashCode() in C# for Better Maintainability 通过覆盖GetHashCode和Equals从IEqualityComparer &lt;&gt;派生外部类的优点 - Advantage of deriving external class from IEqualityComparer<> over overriding GetHashCode and Equals 覆盖类上的GetHashCode和Equals,因为它在字典中使用 - Overriding GetHashCode and Equals on a class because it's used in a dictionary 重写Equals和GetHashCode不一定会覆盖相等重载运算符 - Overriding Equals and GetHashCode doesn't necessarily override equality overloading operator 覆盖GetHashCode() - Overriding GetHashCode()
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM