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 であると仮定する valuetypes には無意味です。

また、等価手順でのハッシュ コード チェックも気にしません。

于 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 に答える