0

对于像 Point3 (例如)这样的引用类型(类),这是一个矫枉过正,缺乏:

#region System.Object Members

public override bool Equals ( object obj )
{
        //return this == ( Point3 ) obj;

        if ( obj == null )
        {
                return false;
        }

        if ( this.GetType ( ) != obj.GetType ( ) )
        {
                return false;
        }

        return this.Equals ( ( Point3 ) obj );
}

public override int GetHashCode ( )
{
        return this.X.GetHashCode ( ) ^ this.Y.GetHashCode ( ) ^ this.Z.GetHashCode ( );
}

public override string ToString ( )
{
        return String.Format ( "[{0}, {1}, {2}]", this.X, this.Y, this.Z );
}

#endregion

#region IEquatable<Point3> Members

public bool Equals ( Point3 other )
{
        if ( other == null )
        {
                return false;
        }

        if ( ReferenceEquals ( this, other ) )
        {
                return true;
        }

        if ( this.GetHashCode ( ) != other.GetHashCode ( ) )
        {
                return false;
        }

        if ( !base.Equals ( other ) )
        {
                return false;
        }

        return this == other;
}

#endregion

public static bool operator == ( Point3 v0, Point3 v1 )
{
        return ( v0.X.IsEqual ( v1.X ) ) && ( v0.Y.IsEqual ( v1.Y ) ) && ( v0.Z.IsEqual ( v1.Z ) );
}

public static bool operator != ( Point3 v0, Point3 v1 )
{
        return !( v0 == v1 );
}

请为值和引用类型进行调整或发布一个新的,我可以在我的基本类型(值和引用)中使用它,而无需在每次我再次实现它时考虑太多。

编辑:这适用于不可变类型。

4

4 回答 4

4

好吧,首先,不要陷入使用 XOR 作为组合运算符生成哈希码的陷阱。

否则,您将遇到以下问题,其中 HC(x) 表示“对象/值 x 的哈希码”:

HC(a,b) = HC(b,a)
HC(a,a) = HC(b,b) = 0

相反,选择至少考虑值顺序的东西,如下所示:

hashcode = 23 // prime number
for each sub-value of the object, do:
    hashcode = hashcode * 31 // another prime number
    hashcode = hashcode + the hashcode of the sub-value

这将尽可能地保留排序。

于 2009-05-30T20:23:04.510 回答
3

this.GetType ( ) != obj.GetType ( )

那会很慢。obj is Type宁可使用。

ReferenceEquals对值类型毫无意义,我认为 Point3 是。

我也不会为相等程序中的哈希码检查而烦恼。

于 2009-05-30T20:22:42.997 回答
2

如果您真的很注重性能并且您的值 x、y 和 z 不会改变(至少经常如此),那么当您进行大量比较时,您可以预先计算您的哈希码。然后在你的平等比较期间很早就使用它。

但在这种情况下最好的方法是:使用分析器找到真正的瓶颈。

于 2009-05-30T20:29:00.143 回答
2

此外,如果您正在创建自己的 Equals 方法,您应该考虑实现 IEquatable。这为您提供了一个很好的相等方法来比较相同的类型,并且通常您可以将 Equals(object) 方法缩减为(对于引用类型):

public override Equals(object other)
{
    Point3 otherP = other as Point3;
    return otherP != null && Equals(otherP); // calls the Equals(Point3) method
}

除了更好一点之外,如果类型是结构,这会减少框操作 - 如果 IEquatable 实现是隐式的,代码将自动使用类型化的 Equals(Point3) 方法,而不是使用涉及装箱操作(并且可能实际上在该方法内进行了拆箱)

于 2009-06-04T13:17:59.567 回答