加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 对于2D点结构体来说,什么是适当的“GetHashCode()”算法(

发布时间:2020-12-15 17:43:44 所属栏目:百科 来源:网络整理
导读:请考虑以下代码: struct Vec2 : IEquatableVec2{ 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
请考虑以下代码:
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,你可以让它做它的事情

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读