对象比较使用哈希码-概念困境

本文关键字:困境 哈希码 比较 对象 | 更新日期: 2023-09-27 18:07:13

我写了一段代码来检查对象是否相等。我从堆栈溢出本身的一个问题中得到了参考。现在,即使我们有两个不同的对象,这段代码仍然为真。有人能解释一下原因吗?

using System;
namespace ConsolePractice
{
    public class Test
    {
        public int Value { get; set; }
        public string String1 { get; set; }
        public string String2 { get; set; }

        public override int GetHashCode()
        {
            int hash = 19;
            hash = hash * 31 + Value;
            hash = hash * 31 + String1.SafeGetHashCode();
            hash = hash * 31 + String2.SafeGetHashCode();
            return hash;
        }
        public override bool Equals(object obj)
        {
            Test test = obj as Test;
            if (obj == null)
            {
                return false;
            }
            return Value == test.Value &&
                String1 == test.String1 &&
                String2 == test.String2;
        }
    }
    class Demo
    {
        static void Main()
        {
            Test p1 = new Test
            {
                Value = 10,
                String1 = "Test1",
                String2 = "Test2"
            };
            Test p2 = new Test
            {
                Value = 10,
                String1 = "Test1",
                String2 = "Test2"
            };
            bool areEqual = p1.Equals(p2);
            Console.WriteLine(areEqual.ToString());
            Console.ReadLine();
        }
    }
}

UtilityClass

 static class utility
    {
        public static int SafeGetHashCode<T>(this T value) where T : class
        {
            return value == null ? 0 : value.GetHashCode();
        }
    }

没有成功后,我尝试了下面的代码,也返回true。我在这里犯了什么大错?请帮助

using System;
using System.Collections.Generic;

class ThingEqualityComparer : IEqualityComparer<Thing>
{
    public bool Equals(Thing x, Thing y)
    {
        if (x == null || y == null)
            return false;
        return (x.Id == y.Id && x.Name == y.Name);
    }
    public int GetHashCode(Thing obj)
    {
        return obj.GetHashCode();
    }
}

public class Thing
{
    public int Id { get; set; }
    public string Name { get; set; }
}
class Demo
{
    static void Main()
    {
        Thing p1 = new Thing
        {
            Id = 10,
            Name = "Test1",
        };
        Thing p2 = new Thing
        {
            Id = 10,
            Name = "Test1",
        };
        var comparer = new ThingEqualityComparer();
        Console.WriteLine(comparer.Equals(p1, p2));

        Console.ReadLine();
    }
}

对象比较使用哈希码-概念困境

您可以重写Equals()GetHashCode()来定义在给定上下文中"equals"的含义。

你的Equals of:

Test test = obj as Test;
if (obj == null)
{
  return false;
}
return Value == test.Value &&
  String1 == test.String1 &&
  String2 == test.String2;

有一个错误,它应该是if(test == null) return false;,否则它说"两个Test对象是相同的,如果他们有相同的Value, String1String2,否则他们不是。"您的GetHashCode()与此一致。

这样,代码返回true:

就不是bug了

现在,即使我们有两个不同的对象,这段代码也会给出true

是的,两个不同的等于对象。

如果你想让EqualsGetHashCode()告诉你它们是否是相同的对象(也就是说,对于一个类的对象只等于它自己),那么根本不要重写EqualsGetHashCode;保持默认行为