GetHashCode()经常重写冲突方式 [英] GetHashCode() override coliding way to often
问题描述
我使用的是unity,而unity中没有元组,因此我创建了自己的元组类,因为我的Dictionary需要它.
I'm using unity, and unity does not have a tuple in it, so I created my own tuple class to work since I needed it for my Dictionary.
Dictionary <Tuple<int,int>, Tile>
我创建的平铺类,与解决该问题并没有真正的联系(至少我认为这无济于事).
Tile class that I created and isn't really relevant to solve this problem(at least I think it wont help).
但是问题是我在元组中同时使用了负整数和正整数,并且当我将当前的 GetHashCode()
与 Tuples
一起使用时,有时得到相同的HashCode,例如 Tuple< -10,8>
和 Tuple< -9,-10>
都在我返回哈希码时给出-172.
But the problem is that I'm using both negative and positive integer in my tuples, and when I use my current GetHashCode()
with the Tuples
, sometimes I get the same HashCode, for example Tuple<-10, 8>
and Tuple<-9,-10>
both gives -172 when I return the hashcode.
是否有任何好的GetHashCode不会让我发生冲突?老实说,我只使用运算符 ==
,因为我需要检查两个元组内部是否具有相同的整数,如果我能得到运算符 ==
只有在两个整数相同且顺序相同时发生冲突,才可以解决我的问题.
Is there any good GetHashCode that wouldn't get me conflicts?
To be honest I'm only using the operator ==
, because I need to check if both tuples have the same integers inside of them, if I could get a operator ==
that only collides when both integer are the same and in the same order, it would solve my problem.
在其他一些小问题上,我无法理解Equals替代方法,因为它确实可以正常工作,但是我不知道它的效果如何,因为我一直在更改每件事,直到它起作用为止.
Some other minor problems, I can't get to understand the Equals override, as it is, it is working, but I don't know how well it works, since I kind of changed every single thing until it worked.
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()
不应冲突.您应该使用它来确定两个事物可能是否是相同的对象,然后您必须进行彻底的检查以查看它们是否相同.
GetHashCode()
isn't supposed to be collision free. You should use it to determine if two things might be the same objects, and then you have to actually do a thorough check to see if they are.
例如,您的==方法应更像这样编写:
For example, your == method should be written more like this:
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);
}
此外,不要忘记考虑 obj1
和 obj2
均为 null
的情况.
Also, don't forget to consider the case where obj1
and obj2
are both null
.
If you're implementing your own Tuple
, you might consider just stealing Microsoft's from the Reference Source repository, or at least use it as a base for your own.
这篇关于GetHashCode()经常重写冲突方式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!