最も堅牢なC#で価値の平等のためのカスタムクラスの実装を等しいです

StackOverflow https://stackoverflow.com/questions/570560

  •  05-09-2019
  •  | 
  •  

質問

私はポイント2クラスを持っている、と私は次のように等しい実装したいとします:

public override bool Equals ( object obj )

public bool Equals ( Point2 obj )

これは、効果的なC#3本からです。

public override bool Equals ( object obj )
{
    // STEP 1: Check for null
    if ( obj == null )
    {
        return false;
    }

    // STEP 3: equivalent data types
    if ( this.GetType ( ) != obj.GetType ( ) )
    {
        return false;
    }
    return Equals ( ( Point2 ) obj );
}

public bool Equals ( Point2 obj )
{
    // STEP 1: Check for null if nullable (e.g., a reference type)
    if ( obj == null )
    {
        return false;
    }
    // STEP 2: Check for ReferenceEquals if this is a reference type
    if ( ReferenceEquals ( this, obj ) )
    {
        return true;
    }
    // STEP 4: Possibly check for equivalent hash codes
    if ( this.GetHashCode ( ) != obj.GetHashCode ( ) )
    {
        return false;
    }
    // STEP 5: Check base.Equals if base overrides Equals()
    System.Diagnostics.Debug.Assert (
        base.GetType ( ) != typeof ( object ) );

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

    // STEP 6: Compare identifying fields for equality.
    return ( ( this.X.Equals ( obj.X ) ) && ( this.Y.Equals ( obj.Y ) ) );
}

やり過ぎということですか?

役に立ちましたか?

解決

継承階層との平等を支援することは難しいです。あなたが意味を正確に何をうまくする必要があります。あなたが本当にここの継承が必要ですか?そうでない場合 - ポイント2は、System.Objectから直接導出し、あなたはそれが密閉させることができれば、生活が少し楽になります。その場合、私が使用することになります:

public override bool Equals (object obj)
{
    return Equals(obj as Point2);
}

public bool Equals (Point2 obj)
{
    // STEP 1: Check for null if nullable (e.g., a reference type)
    // Note use of ReferenceEquals in case you overload ==.
    if (object.ReferenceEquals(obj, null))
    {
        return false;
    }

    // STEP 2: Check for ReferenceEquals if this is a reference type
    // Skip this or not? With only two fields to check, it's probably
    // not worth it. If the later checks are costly, it could be.
    if (object.ReferenceEquals( this, obj))
    {
        return true;
    }

    // STEP 4: Possibly check for equivalent hash codes
    // Skipped in this case: would be *less* efficient

    // STEP 5: Check base.Equals if base overrides Equals()
    // Skipped in this case

    // STEP 6: Compare identifying fields for equality.
    // In this case I'm using == instead of Equals for brevity
    // - assuming X and Y are of a type which overloads ==.
    return this.X == obj.X && this.Y == obj.Y;
}

他のヒント

本当にない - あなたはほとんどすべての可能性を占めています。このコードは、スクラッチアプリケーション以外である場合は奇妙なオブジェクトの平等の挙動による論理エラーは、デバッグに痛みを伴うので、あなたは、このアプローチの利点を考慮する必要があります。

あなたが望む正確に何のように私には見えます。そのブロック全体がに沸くます:

は、「それはまったく同じインスタンスの場合は、trueを返す。彼らは同じXとYの値を持つ別々のインスタンスであれば、trueを返します。他のすべての例(ヌル、異なるタイプ、異なるX / Y値)はfalseを返します。」

は、私がはequalsメソッドのために書きたいと思いよりも、その確かに多くのコード。このようも参照してハッシュコードをチェックするなどの冗長チェックがたくさんあります(私はこれらのチェックが重複している知っているので、構造的平等のためのあなたの機能チェックの最後の行)。シンプルで読みやすいコードに焦点を当てています。

public bool Equals(object o)
{
    Point2 p = o as Point2;
    if (o != null)
        return this.X == o.X && this.Y == o.Y;
    else
        return false;
}

あなたのequalsメソッドは、構造的な平等を使用しているので、あなたにも、あなたのフィールドに基づいて実装してGetHashCodeメソッドをオーバーライドすることを確認します。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top