c# - GetHashCode() 经常重写冲突方式

标签 c# unity3d overriding hashcode gethashcode

我正在使用 unity,而 unity 中没有元组,所以我创建了自己的元组类来工作,因为我的字典需要它。

Dictionary <Tuple<int,int>, Tile>

我创建的 Tile 类与解决这个问题并不相关(至少我认为它不会有帮助)。

但问题是我在我的元组中同时使用了负整数和正整数,当我使用当前的 GetHashCode() 时与 Tuples ,有时我会得到相同的 HashCode,例如 Tuple<-10, 8>Tuple<-9,-10>当我返回哈希码时,两者都给出 -172。

有没有好的 GetHashCode 不会让我产生冲突? 老实说,我只使用运算符 == ,因为我需要检查两个元组内部是否有相同的整数,如果我能得到一个运算符 ==只有当两个整数相同且顺序相同时才会发生冲突,它会解决我的问题。

其他一些小问题,我无法理解 Equals 覆盖,因为它正在工作,但我不知道它工作得如何,因为我改变了每一件事直到它工作。

public class Tuple<T1, T2>
{
    public T1 First { get; private set; }
    public T2 Second { get; private set; }

    public Tuple(T1 _First, T2 _Second)
    {
        First = _First;
        Second = _Second;
    }
    public override int GetHashCode()
    {
        int hash = 0;

        hash = First.GetHashCode() * 17 + Second.GetHashCode() + First.GetHashCode();

        return hash;
    }
    public static bool operator==(Tuple<T1, T2> obj1, Tuple<T1, T2> obj2)
    {
        if (ReferenceEquals(null, obj2))
            return false;
        return (obj1.GetHashCode() == obj2.GetHashCode());
    }
    public static bool operator!=(Tuple<T1, T2> obj1, Tuple<T1, T2> obj2)
    {
        if (ReferenceEquals(null, obj2))
            return true;
        return !(obj1.GetHashCode() == obj2.GetHashCode());
    }
    public bool Equals(Tuple<T1, T2> other)
    {
        if (other == null)
            return false;

        if (GetHashCode() == other.GetHashCode())
            return true;
        else
            return false;

    }
    public override bool Equals(object obj)
    {
        if (ReferenceEquals(null, obj))
        {
            return false;
        }
        if (ReferenceEquals(this, obj))
        {
            return true;
        }

        Tuple<T1, T2> other = obj as Tuple<T1, T2>;

        return obj.GetType() == GetType() && Equals(other);
    }
}
public static class Tuple
{
    public static Tuple<T1, T2> New<T1, T2>(T1 first, T2 second)
    {
        var tuple = new Tuple<T1, T2>(first, second);
        return tuple;
    }
}

最佳答案

GetHashCode() 不应该是无碰撞的。您应该使用它来确定两个事物是否可能是相同的对象,然后您必须实际进行彻底检查以查看它们是否是。

比如你的==方法更应该这样写:

public static bool operator==(Tuple<T1, T2> obj1, Tuple<T1, T2> obj2)
{
    if (ReferenceEquals(null, obj2))
        return false;

    if (obj1.GetHashCode() != obj2.GetHashCode())
    {
        return false;
    }
    return DefaultComparer<T1>.Equals(obj1.First, obj2.First) && DefaultComparer<T2>.Equals(obj1.Second, obj2.Second);
}

另外,不要忘记考虑 obj1obj2 都是 null 的情况。

如果您要实现自己的元组,您可能会考虑从Reference Source 中窃取Microsoft 的元组。存储库,或者至少将其用作您自己的基础。

关于c# - GetHashCode() 经常重写冲突方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51833137/

相关文章:

c# - 输入.GetButtonDown ("Jump");在 Unity 中不适用于空格键

c# - 使用 moonsharp 将 C# 对象传递到 lua 函数中。

Javascript - 覆盖克隆库中继承的方法

java - hashCode 和 Equals 在 Map 键中无法正常工作

c# - 关于应用程序在 XP/W2K3 中没有获得焦点的问题

c# - nunit 测试仅在作为 tfs msbuild 进程的一部分运行时抛出异常

c# - asp.net将匿名函数参数转换为字符串

android - 如何让用户在 unity android 游戏中选择照片?

php - block 未从数据库中删除

c# - Xamarin:不传播任务引发的异常