c# – 对于2D点结构体来说,什么是适当的“GetHashCode()”算法(
请考虑以下代码:
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(); } } 除了比较双重平等的对话(这只是演示代码),我关心的是当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 !!!!! 这应该在字典集合中破坏破坏.所以问题是如何为2,3或甚至4个浮点值形成GetHashCode()函数,以使结果不对称,并且哈希值不会冲突. 编辑1: Point实现不适当的x ^ y解,PointF包装ValueType.GetHashCode(). 矩形具有非常特殊的((X((Y <13)|(Y> 19)))((宽度<26)|(宽度> 6)) )^((高度< 7)|(高度>> 25)))表达式,这似乎按预期的方式执行. 编辑2: ‘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))); } 解决方法
Jon skeet有这个涵盖:
What is the best algorithm for an overridden 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; } } 另外,将您的Equals(object)实现更改为: return Equals(obj as FVector2); 然而,请注意,这可以感知派生类型相等.如果你不想这样做,你必须比较其他类型的类型(.GetType()与typeof(FVector2)(并且不要忘记无效检查)感谢指出它是一个结构体,LukH Resharper有一个很好的代码生成相等和哈希码,所以如果你有resharper,你可以让它做它的事情 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |