ja7*_*a72 13 c# point hashcode
请考虑以下代码:
struct Vec2 : IEquatable<Vec2>
{
double X,Y;
public bool Equals(Vec2 other)
{
return X.Equals(other.X) && Y.Equals(other.Y);
}
public override bool Equals(object obj)
{
if (obj is Vec2)
{
return Equals((Vec2)obj);
}
return false;
}
// this will return the same value when X, Y are swapped
public override int GetHashCode()
{
return X.GetHashCode() ^ Y.GetHashCode();
}
}
Run Code Online (Sandbox Code Playgroud)
除了比较双精度的平等对话(这只是演示代码)之外,我关注的是当X,Y值被交换时存在哈希冲突.例如:
Vec2 A = new Vec2() { X=1, Y=5 };
Vec2 B = new Vec2() { X=5, Y=1 };
bool test1 = A.Equals(B); // returns false;
bool test2 = A.GetHashCode() == B.GetHashCode() // returns true !!!!!
Run Code Online (Sandbox Code Playgroud)
这应该破坏字典集合中的破坏.所以问题是如何GetHashCode()为2,3或甚至4个浮点值的函数形成属性,使得结果不对称且散列不会发生冲突.
Point实现不适当的x ^ y解决方案,并PointF包装ValueType.GetHashCode().
Rectangle(((X ^ ((Y << 13) | (Y >> 19))) ^ ((Width << 26) | (Width >> 6))) ^ ((Height << 7) | (Height >> 25)))哈希码有一个非常奇特的表达式,它似乎按预期执行.
'System.Double'有一个很好的实现,因为它不认为每个位同样重要
public override unsafe int GetHashCode() //from System.Double
{
double num = this;
if (num == 0.0)
{
return 0;
}
long num2 = *((long*) &num);
return (((int) num2) ^ ((int) (num2 >> 32)));
}
Run Code Online (Sandbox Code Playgroud)
Oha*_*der 20
乔恩双向飞碟有这个涵盖:
重写System.Object.GetHashCode的最佳算法是什么?
public override int GetHashCode()
{
unchecked // Overflow is fine, just wrap
{
int hash = 17;
// Suitable nullity checks etc, of course :)
hash = hash * 23 + X.GetHashCode();
hash = hash * 23 + Y.GetHashCode();
return hash;
}
}
Run Code Online (Sandbox Code Playgroud)
另外,将您的Equals(object)实施更改为:
return Equals(obj as FVector2);
Run Code Online (Sandbox Code Playgroud)
但请注意,这可以感知派生类型是相等的.如果你不希望出现这种情况,你必须比较的运行时类型 感谢您指出这是一个结构,LukHother.GetType()有typeof(FVector2)(不要忘记检查无效)
Resharper对于相等和哈希代码有很好的代码生成,所以如果你有resharper,你可以让它做它的事情